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