Profiler.cc revision 10919:80069a602c83
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)
64{
65    m_hot_lines = p->hot_lines;
66    m_all_instructions = p->all_instructions;
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    uint32_t numVNets = Network::getNumberOfVirtualNetworks();
101    for (int i = 0; i < numVNets; i++) {
102        delayVCHistogram.push_back(new Stats::Histogram());
103        delayVCHistogram[i]
104            ->init(10)
105            .name(pName + csprintf(".delayVCHist.vnet_%i", i))
106            .desc(csprintf("delay histogram for vnet_%i", i))
107            .flags(Stats::nozero | Stats::pdf | Stats::oneline);
108    }
109
110    m_outstandReqHist
111        .init(10)
112        .name(pName + ".outstanding_req_hist")
113        .desc("")
114        .flags(Stats::nozero | Stats::pdf | Stats::oneline);
115
116    m_latencyHist
117        .init(10)
118        .name(pName + ".latency_hist")
119        .desc("")
120        .flags(Stats::nozero | Stats::pdf | Stats::oneline);
121
122    m_hitLatencyHist
123        .init(10)
124        .name(pName + ".hit_latency_hist")
125        .desc("")
126        .flags(Stats::nozero | Stats::pdf | Stats::oneline);
127
128    m_missLatencyHist
129        .init(10)
130        .name(pName + ".miss_latency_hist")
131        .desc("")
132        .flags(Stats::nozero | Stats::pdf | Stats::oneline);
133
134    for (int i = 0; i < RubyRequestType_NUM; i++) {
135        m_typeLatencyHist.push_back(new Stats::Histogram());
136        m_typeLatencyHist[i]
137            ->init(10)
138            .name(pName + csprintf(".%s.latency_hist",
139                                    RubyRequestType(i)))
140            .desc("")
141            .flags(Stats::nozero | Stats::pdf | Stats::oneline);
142
143        m_hitTypeLatencyHist.push_back(new Stats::Histogram());
144        m_hitTypeLatencyHist[i]
145            ->init(10)
146            .name(pName + csprintf(".%s.hit_latency_hist",
147                                    RubyRequestType(i)))
148            .desc("")
149            .flags(Stats::nozero | Stats::pdf | Stats::oneline);
150
151        m_missTypeLatencyHist.push_back(new Stats::Histogram());
152        m_missTypeLatencyHist[i]
153            ->init(10)
154            .name(pName + csprintf(".%s.miss_latency_hist",
155                                    RubyRequestType(i)))
156            .desc("")
157            .flags(Stats::nozero | Stats::pdf | Stats::oneline);
158    }
159
160    for (int i = 0; i < MachineType_NUM; i++) {
161        m_hitMachLatencyHist.push_back(new Stats::Histogram());
162        m_hitMachLatencyHist[i]
163            ->init(10)
164            .name(pName + csprintf(".%s.hit_mach_latency_hist",
165                                    MachineType(i)))
166            .desc("")
167            .flags(Stats::nozero | Stats::pdf | Stats::oneline);
168
169        m_missMachLatencyHist.push_back(new Stats::Histogram());
170        m_missMachLatencyHist[i]
171            ->init(10)
172            .name(pName + csprintf(".%s.miss_mach_latency_hist",
173                                    MachineType(i)))
174            .desc("")
175            .flags(Stats::nozero | Stats::pdf | Stats::oneline);
176
177        m_IssueToInitialDelayHist.push_back(new Stats::Histogram());
178        m_IssueToInitialDelayHist[i]
179            ->init(10)
180            .name(pName + csprintf(
181                ".%s.miss_latency_hist.issue_to_initial_request",
182                MachineType(i)))
183            .desc("")
184            .flags(Stats::nozero | Stats::pdf | Stats::oneline);
185
186        m_InitialToForwardDelayHist.push_back(new Stats::Histogram());
187        m_InitialToForwardDelayHist[i]
188            ->init(10)
189            .name(pName + csprintf(".%s.miss_latency_hist.initial_to_forward",
190                                   MachineType(i)))
191            .desc("")
192            .flags(Stats::nozero | Stats::pdf | Stats::oneline);
193
194        m_ForwardToFirstResponseDelayHist.push_back(new Stats::Histogram());
195        m_ForwardToFirstResponseDelayHist[i]
196            ->init(10)
197            .name(pName + csprintf(
198                ".%s.miss_latency_hist.forward_to_first_response",
199                MachineType(i)))
200            .desc("")
201            .flags(Stats::nozero | Stats::pdf | Stats::oneline);
202
203        m_FirstResponseToCompletionDelayHist.push_back(new Stats::Histogram());
204        m_FirstResponseToCompletionDelayHist[i]
205            ->init(10)
206            .name(pName + csprintf(
207                ".%s.miss_latency_hist.first_response_to_completion",
208                MachineType(i)))
209            .desc("")
210            .flags(Stats::nozero | Stats::pdf | Stats::oneline);
211
212        m_IncompleteTimes[i]
213            .name(pName + csprintf(".%s.incomplete_times", MachineType(i)))
214            .desc("")
215            .flags(Stats::nozero);
216    }
217
218    for (int i = 0; i < RubyRequestType_NUM; i++) {
219        m_hitTypeMachLatencyHist.push_back(std::vector<Stats::Histogram *>());
220        m_missTypeMachLatencyHist.push_back(std::vector<Stats::Histogram *>());
221
222        for (int j = 0; j < MachineType_NUM; j++) {
223            m_hitTypeMachLatencyHist[i].push_back(new Stats::Histogram());
224            m_hitTypeMachLatencyHist[i][j]
225                ->init(10)
226                .name(pName + csprintf(".%s.%s.hit_type_mach_latency_hist",
227                                       RubyRequestType(i), MachineType(j)))
228                .desc("")
229                .flags(Stats::nozero | Stats::pdf | Stats::oneline);
230
231            m_missTypeMachLatencyHist[i].push_back(new Stats::Histogram());
232            m_missTypeMachLatencyHist[i][j]
233                ->init(10)
234                .name(pName + csprintf(".%s.%s.miss_type_mach_latency_hist",
235                                       RubyRequestType(i), MachineType(j)))
236                .desc("")
237                .flags(Stats::nozero | Stats::pdf | Stats::oneline);
238        }
239    }
240}
241
242void
243Profiler::collateStats()
244{
245    if (!m_all_instructions) {
246        m_address_profiler_ptr->collateStats();
247    }
248
249    if (m_all_instructions) {
250        m_inst_profiler_ptr->collateStats();
251    }
252
253    uint32_t numVNets = Network::getNumberOfVirtualNetworks();
254    for (uint32_t i = 0; i < MachineType_NUM; i++) {
255        for (map<uint32_t, AbstractController*>::iterator it =
256                  g_abs_controls[i].begin();
257             it != g_abs_controls[i].end(); ++it) {
258
259            AbstractController *ctr = (*it).second;
260            delayHistogram.add(ctr->getDelayHist());
261
262            for (uint32_t i = 0; i < numVNets; i++) {
263                delayVCHistogram[i]->add(ctr->getDelayVCHist(i));
264            }
265        }
266    }
267
268    for (uint32_t i = 0; i < MachineType_NUM; i++) {
269        for (map<uint32_t, AbstractController*>::iterator it =
270                g_abs_controls[i].begin();
271                it != g_abs_controls[i].end(); ++it) {
272
273            AbstractController *ctr = (*it).second;
274            Sequencer *seq = ctr->getSequencer();
275            if (seq != NULL) {
276                m_outstandReqHist.add(seq->getOutstandReqHist());
277            }
278        }
279    }
280
281    for (uint32_t i = 0; i < MachineType_NUM; i++) {
282        for (map<uint32_t, AbstractController*>::iterator it =
283                g_abs_controls[i].begin();
284                it != g_abs_controls[i].end(); ++it) {
285
286            AbstractController *ctr = (*it).second;
287            Sequencer *seq = ctr->getSequencer();
288            if (seq != NULL) {
289                // add all the latencies
290                m_latencyHist.add(seq->getLatencyHist());
291                m_hitLatencyHist.add(seq->getHitLatencyHist());
292                m_missLatencyHist.add(seq->getMissLatencyHist());
293
294                // add the per request type latencies
295                for (uint32_t j = 0; j < RubyRequestType_NUM; ++j) {
296                    m_typeLatencyHist[j]
297                        ->add(seq->getTypeLatencyHist(j));
298                    m_hitTypeLatencyHist[j]
299                        ->add(seq->getHitTypeLatencyHist(j));
300                    m_missTypeLatencyHist[j]
301                        ->add(seq->getMissTypeLatencyHist(j));
302                }
303
304                // add the per machine type miss latencies
305                for (uint32_t j = 0; j < MachineType_NUM; ++j) {
306                    m_hitMachLatencyHist[j]
307                        ->add(seq->getHitMachLatencyHist(j));
308                    m_missMachLatencyHist[j]
309                        ->add(seq->getMissMachLatencyHist(j));
310
311                    m_IssueToInitialDelayHist[j]->add(
312                        seq->getIssueToInitialDelayHist(MachineType(j)));
313
314                    m_InitialToForwardDelayHist[j]->add(
315                        seq->getInitialToForwardDelayHist(MachineType(j)));
316                    m_ForwardToFirstResponseDelayHist[j]->add(seq->
317                        getForwardRequestToFirstResponseHist(MachineType(j)));
318
319                    m_FirstResponseToCompletionDelayHist[j]->add(seq->
320                        getFirstResponseToCompletionDelayHist(
321                            MachineType(j)));
322                    m_IncompleteTimes[j] +=
323                        seq->getIncompleteTimes(MachineType(j));
324                }
325
326                // add the per (request, machine) type miss latencies
327                for (uint32_t j = 0; j < RubyRequestType_NUM; j++) {
328                    for (uint32_t k = 0; k < MachineType_NUM; k++) {
329                        m_hitTypeMachLatencyHist[j][k]->add(
330                                seq->getHitTypeMachLatencyHist(j,k));
331                        m_missTypeMachLatencyHist[j][k]->add(
332                                seq->getMissTypeMachLatencyHist(j,k));
333                    }
334                }
335            }
336        }
337    }
338}
339
340void
341Profiler::addAddressTraceSample(const RubyRequest& msg, NodeID id)
342{
343    if (msg.getType() != RubyRequestType_IFETCH) {
344        // Note: The following line should be commented out if you
345        // want to use the special profiling that is part of the GS320
346        // protocol
347
348        // NOTE: Unless PROFILE_HOT_LINES is enabled, nothing will be
349        // profiled by the AddressProfiler
350        m_address_profiler_ptr->
351            addTraceSample(msg.getLineAddress(), msg.getProgramCounter(),
352                           msg.getType(), msg.getAccessMode(), id, false);
353    }
354}
355