Profiler.cc revision 11172:9261e98e4501
1/*
2 * Copyright (c) 1999-2013 Mark D. Hill and David A. Wood
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/*
30   This file has been modified by Kevin Moore and Dan Nussbaum of the
31   Scalable Systems Research Group at Sun Microsystems Laboratories
32   (http://research.sun.com/scalable/) to support the Adaptive
33   Transactional Memory Test Platform (ATMTP).
34
35   Please send email to atmtp-interest@sun.com with feedback, questions, or
36   to request future announcements about ATMTP.
37
38   ----------------------------------------------------------------------
39
40   File modification date: 2008-02-23
41
42   ----------------------------------------------------------------------
43*/
44
45#include <sys/types.h>
46#include <unistd.h>
47
48#include <algorithm>
49#include <fstream>
50
51#include "base/stl_helpers.hh"
52#include "base/str.hh"
53#include "mem/protocol/MachineType.hh"
54#include "mem/protocol/RubyRequest.hh"
55#include "mem/ruby/network/Network.hh"
56#include "mem/ruby/profiler/AddressProfiler.hh"
57#include "mem/ruby/profiler/Profiler.hh"
58#include "mem/ruby/system/Sequencer.hh"
59
60using namespace std;
61using m5::stl_helpers::operator<<;
62
63Profiler::Profiler(const RubySystemParams *p, RubySystem *rs)
64    : m_ruby_system(rs), m_hot_lines(p->hot_lines),
65      m_all_instructions(p->all_instructions),
66      m_num_vnets(p->number_of_virtual_networks)
67{
68    m_address_profiler_ptr = new AddressProfiler(p->num_of_sequencers, this);
69    m_address_profiler_ptr->setHotLines(m_hot_lines);
70    m_address_profiler_ptr->setAllInstructions(m_all_instructions);
71
72    if (m_all_instructions) {
73        m_inst_profiler_ptr = new AddressProfiler(p->num_of_sequencers, this);
74        m_inst_profiler_ptr->setHotLines(m_hot_lines);
75        m_inst_profiler_ptr->setAllInstructions(m_all_instructions);
76    }
77}
78
79Profiler::~Profiler()
80{
81}
82
83void
84Profiler::regStats(const std::string &pName)
85{
86    if (!m_all_instructions) {
87        m_address_profiler_ptr->regStats(pName);
88    }
89
90    if (m_all_instructions) {
91        m_inst_profiler_ptr->regStats(pName);
92    }
93
94    delayHistogram
95        .init(10)
96        .name(pName + ".delayHist")
97        .desc("delay histogram for all message")
98        .flags(Stats::nozero | Stats::pdf | Stats::oneline);
99
100    for (int i = 0; i < m_num_vnets; i++) {
101        delayVCHistogram.push_back(new Stats::Histogram());
102        delayVCHistogram[i]
103            ->init(10)
104            .name(pName + csprintf(".delayVCHist.vnet_%i", i))
105            .desc(csprintf("delay histogram for vnet_%i", i))
106            .flags(Stats::nozero | Stats::pdf | Stats::oneline);
107    }
108
109    m_outstandReqHist
110        .init(10)
111        .name(pName + ".outstanding_req_hist")
112        .desc("")
113        .flags(Stats::nozero | Stats::pdf | Stats::oneline);
114
115    m_latencyHist
116        .init(10)
117        .name(pName + ".latency_hist")
118        .desc("")
119        .flags(Stats::nozero | Stats::pdf | Stats::oneline);
120
121    m_hitLatencyHist
122        .init(10)
123        .name(pName + ".hit_latency_hist")
124        .desc("")
125        .flags(Stats::nozero | Stats::pdf | Stats::oneline);
126
127    m_missLatencyHist
128        .init(10)
129        .name(pName + ".miss_latency_hist")
130        .desc("")
131        .flags(Stats::nozero | Stats::pdf | Stats::oneline);
132
133    for (int i = 0; i < RubyRequestType_NUM; i++) {
134        m_typeLatencyHist.push_back(new Stats::Histogram());
135        m_typeLatencyHist[i]
136            ->init(10)
137            .name(pName + csprintf(".%s.latency_hist",
138                                    RubyRequestType(i)))
139            .desc("")
140            .flags(Stats::nozero | Stats::pdf | Stats::oneline);
141
142        m_hitTypeLatencyHist.push_back(new Stats::Histogram());
143        m_hitTypeLatencyHist[i]
144            ->init(10)
145            .name(pName + csprintf(".%s.hit_latency_hist",
146                                    RubyRequestType(i)))
147            .desc("")
148            .flags(Stats::nozero | Stats::pdf | Stats::oneline);
149
150        m_missTypeLatencyHist.push_back(new Stats::Histogram());
151        m_missTypeLatencyHist[i]
152            ->init(10)
153            .name(pName + csprintf(".%s.miss_latency_hist",
154                                    RubyRequestType(i)))
155            .desc("")
156            .flags(Stats::nozero | Stats::pdf | Stats::oneline);
157    }
158
159    for (int i = 0; i < MachineType_NUM; i++) {
160        m_hitMachLatencyHist.push_back(new Stats::Histogram());
161        m_hitMachLatencyHist[i]
162            ->init(10)
163            .name(pName + csprintf(".%s.hit_mach_latency_hist",
164                                    MachineType(i)))
165            .desc("")
166            .flags(Stats::nozero | Stats::pdf | Stats::oneline);
167
168        m_missMachLatencyHist.push_back(new Stats::Histogram());
169        m_missMachLatencyHist[i]
170            ->init(10)
171            .name(pName + csprintf(".%s.miss_mach_latency_hist",
172                                    MachineType(i)))
173            .desc("")
174            .flags(Stats::nozero | Stats::pdf | Stats::oneline);
175
176        m_IssueToInitialDelayHist.push_back(new Stats::Histogram());
177        m_IssueToInitialDelayHist[i]
178            ->init(10)
179            .name(pName + csprintf(
180                ".%s.miss_latency_hist.issue_to_initial_request",
181                MachineType(i)))
182            .desc("")
183            .flags(Stats::nozero | Stats::pdf | Stats::oneline);
184
185        m_InitialToForwardDelayHist.push_back(new Stats::Histogram());
186        m_InitialToForwardDelayHist[i]
187            ->init(10)
188            .name(pName + csprintf(".%s.miss_latency_hist.initial_to_forward",
189                                   MachineType(i)))
190            .desc("")
191            .flags(Stats::nozero | Stats::pdf | Stats::oneline);
192
193        m_ForwardToFirstResponseDelayHist.push_back(new Stats::Histogram());
194        m_ForwardToFirstResponseDelayHist[i]
195            ->init(10)
196            .name(pName + csprintf(
197                ".%s.miss_latency_hist.forward_to_first_response",
198                MachineType(i)))
199            .desc("")
200            .flags(Stats::nozero | Stats::pdf | Stats::oneline);
201
202        m_FirstResponseToCompletionDelayHist.push_back(new Stats::Histogram());
203        m_FirstResponseToCompletionDelayHist[i]
204            ->init(10)
205            .name(pName + csprintf(
206                ".%s.miss_latency_hist.first_response_to_completion",
207                MachineType(i)))
208            .desc("")
209            .flags(Stats::nozero | Stats::pdf | Stats::oneline);
210
211        m_IncompleteTimes[i]
212            .name(pName + csprintf(".%s.incomplete_times", MachineType(i)))
213            .desc("")
214            .flags(Stats::nozero);
215    }
216
217    for (int i = 0; i < RubyRequestType_NUM; i++) {
218        m_hitTypeMachLatencyHist.push_back(std::vector<Stats::Histogram *>());
219        m_missTypeMachLatencyHist.push_back(std::vector<Stats::Histogram *>());
220
221        for (int j = 0; j < MachineType_NUM; j++) {
222            m_hitTypeMachLatencyHist[i].push_back(new Stats::Histogram());
223            m_hitTypeMachLatencyHist[i][j]
224                ->init(10)
225                .name(pName + csprintf(".%s.%s.hit_type_mach_latency_hist",
226                                       RubyRequestType(i), MachineType(j)))
227                .desc("")
228                .flags(Stats::nozero | Stats::pdf | Stats::oneline);
229
230            m_missTypeMachLatencyHist[i].push_back(new Stats::Histogram());
231            m_missTypeMachLatencyHist[i][j]
232                ->init(10)
233                .name(pName + csprintf(".%s.%s.miss_type_mach_latency_hist",
234                                       RubyRequestType(i), MachineType(j)))
235                .desc("")
236                .flags(Stats::nozero | Stats::pdf | Stats::oneline);
237        }
238    }
239}
240
241void
242Profiler::collateStats()
243{
244    if (!m_all_instructions) {
245        m_address_profiler_ptr->collateStats();
246    }
247
248    if (m_all_instructions) {
249        m_inst_profiler_ptr->collateStats();
250    }
251
252    for (uint32_t i = 0; i < MachineType_NUM; i++) {
253        for (map<uint32_t, AbstractController*>::iterator it =
254                  m_ruby_system->m_abstract_controls[i].begin();
255             it != m_ruby_system->m_abstract_controls[i].end(); ++it) {
256
257            AbstractController *ctr = (*it).second;
258            delayHistogram.add(ctr->getDelayHist());
259
260            for (uint32_t i = 0; i < m_num_vnets; i++) {
261                delayVCHistogram[i]->add(ctr->getDelayVCHist(i));
262            }
263        }
264    }
265
266    for (uint32_t i = 0; i < MachineType_NUM; i++) {
267        for (map<uint32_t, AbstractController*>::iterator it =
268                m_ruby_system->m_abstract_controls[i].begin();
269                it != m_ruby_system->m_abstract_controls[i].end(); ++it) {
270
271            AbstractController *ctr = (*it).second;
272            Sequencer *seq = ctr->getSequencer();
273            if (seq != NULL) {
274                m_outstandReqHist.add(seq->getOutstandReqHist());
275            }
276        }
277    }
278
279    for (uint32_t i = 0; i < MachineType_NUM; i++) {
280        for (map<uint32_t, AbstractController*>::iterator it =
281                m_ruby_system->m_abstract_controls[i].begin();
282                it != m_ruby_system->m_abstract_controls[i].end(); ++it) {
283
284            AbstractController *ctr = (*it).second;
285            Sequencer *seq = ctr->getSequencer();
286            if (seq != NULL) {
287                // add all the latencies
288                m_latencyHist.add(seq->getLatencyHist());
289                m_hitLatencyHist.add(seq->getHitLatencyHist());
290                m_missLatencyHist.add(seq->getMissLatencyHist());
291
292                // add the per request type latencies
293                for (uint32_t j = 0; j < RubyRequestType_NUM; ++j) {
294                    m_typeLatencyHist[j]
295                        ->add(seq->getTypeLatencyHist(j));
296                    m_hitTypeLatencyHist[j]
297                        ->add(seq->getHitTypeLatencyHist(j));
298                    m_missTypeLatencyHist[j]
299                        ->add(seq->getMissTypeLatencyHist(j));
300                }
301
302                // add the per machine type miss latencies
303                for (uint32_t j = 0; j < MachineType_NUM; ++j) {
304                    m_hitMachLatencyHist[j]
305                        ->add(seq->getHitMachLatencyHist(j));
306                    m_missMachLatencyHist[j]
307                        ->add(seq->getMissMachLatencyHist(j));
308
309                    m_IssueToInitialDelayHist[j]->add(
310                        seq->getIssueToInitialDelayHist(MachineType(j)));
311
312                    m_InitialToForwardDelayHist[j]->add(
313                        seq->getInitialToForwardDelayHist(MachineType(j)));
314                    m_ForwardToFirstResponseDelayHist[j]->add(seq->
315                        getForwardRequestToFirstResponseHist(MachineType(j)));
316
317                    m_FirstResponseToCompletionDelayHist[j]->add(seq->
318                        getFirstResponseToCompletionDelayHist(
319                            MachineType(j)));
320                    m_IncompleteTimes[j] +=
321                        seq->getIncompleteTimes(MachineType(j));
322                }
323
324                // add the per (request, machine) type miss latencies
325                for (uint32_t j = 0; j < RubyRequestType_NUM; j++) {
326                    for (uint32_t k = 0; k < MachineType_NUM; k++) {
327                        m_hitTypeMachLatencyHist[j][k]->add(
328                                seq->getHitTypeMachLatencyHist(j,k));
329                        m_missTypeMachLatencyHist[j][k]->add(
330                                seq->getMissTypeMachLatencyHist(j,k));
331                    }
332                }
333            }
334        }
335    }
336}
337
338void
339Profiler::addAddressTraceSample(const RubyRequest& msg, NodeID id)
340{
341    if (msg.getType() != RubyRequestType_IFETCH) {
342        // Note: The following line should be commented out if you
343        // want to use the special profiling that is part of the GS320
344        // protocol
345
346        // NOTE: Unless PROFILE_HOT_LINES is enabled, nothing will be
347        // profiled by the AddressProfiler
348        m_address_profiler_ptr->
349            addTraceSample(msg.getLineAddress(), msg.getProgramCounter(),
350                           msg.getType(), msg.getAccessMode(), id, false);
351    }
352}
353