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