2 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
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.
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.
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).
35 Please send email to atmtp-interest@sun.com with feedback, questions, or
36 to request future announcements about ATMTP.
38 ----------------------------------------------------------------------
40 File modification date: 2008-02-23
42 ----------------------------------------------------------------------
45 // Allows use of times() library call, which determines virtual runtime
46 #include <sys/resource.h>
47 #include <sys/times.h>
48 #include <sys/types.h>
54 #include "base/stl_helpers.hh"
55 #include "base/str.hh"
56 #include "mem/protocol/MachineType.hh"
57 #include "mem/protocol/RubyRequest.hh"
58 #include "mem/ruby/network/Network.hh"
59 #include "mem/ruby/profiler/AddressProfiler.hh"
60 #include "mem/ruby/profiler/Profiler.hh"
61 #include "mem/ruby/system/System.hh"
64 using m5::stl_helpers::operator<<;
66 static double process_memory_total();
67 static double process_memory_resident();
69 Profiler::Profiler(const Params
*p
)
70 : SimObject(p
), m_event(this)
72 m_inst_profiler_ptr
= NULL
;
73 m_address_profiler_ptr
= NULL
;
75 m_real_time_start_time
= time(NULL
); // Not reset in clearStats()
76 m_stats_period
= 1000000; // Default
77 m_periodic_output_file_ptr
= &cerr
;
79 m_hot_lines
= p
->hot_lines
;
80 m_all_instructions
= p
->all_instructions
;
82 m_num_of_sequencers
= p
->num_of_sequencers
;
85 m_all_instructions
= false;
87 m_address_profiler_ptr
= new AddressProfiler(m_num_of_sequencers
);
88 m_address_profiler_ptr
->setHotLines(m_hot_lines
);
89 m_address_profiler_ptr
->setAllInstructions(m_all_instructions
);
91 if (m_all_instructions
) {
92 m_inst_profiler_ptr
= new AddressProfiler(m_num_of_sequencers
);
93 m_inst_profiler_ptr
->setHotLines(m_hot_lines
);
94 m_inst_profiler_ptr
->setAllInstructions(m_all_instructions
);
97 p
->ruby_system
->registerProfiler(this);
100 Profiler::~Profiler()
102 if (m_periodic_output_file_ptr
!= &cerr
) {
103 delete m_periodic_output_file_ptr
;
110 // FIXME - avoid the repeated code
112 vector
<int64_t> perProcCycleCount(m_num_of_sequencers
);
114 for (int i
= 0; i
< m_num_of_sequencers
; i
++) {
115 perProcCycleCount
[i
] =
116 g_system_ptr
->getTime() - m_cycles_executed_at_start
[i
] + 1;
117 // The +1 allows us to avoid division by zero
120 ostream
&out
= *m_periodic_output_file_ptr
;
122 out
<< "ruby_cycles: " << g_system_ptr
->getTime()-m_ruby_start
<< endl
123 << "mbytes_resident: " << process_memory_resident() << endl
124 << "mbytes_total: " << process_memory_total() << endl
;
126 if (process_memory_total() > 0) {
127 out
<< "resident_ratio: "
128 << process_memory_resident() / process_memory_total() << endl
;
131 out
<< "miss_latency: " << m_allMissLatencyHistogram
<< endl
;
135 if (m_all_instructions
) {
136 m_inst_profiler_ptr
->printStats(out
);
139 //g_system_ptr->getNetwork()->printStats(out);
140 schedule(m_event
, g_system_ptr
->clockEdge(Cycles(m_stats_period
)));
144 Profiler::setPeriodicStatsFile(const string
& filename
)
146 cout
<< "Recording periodic statistics to file '" << filename
<< "' every "
147 << m_stats_period
<< " Ruby cycles" << endl
;
149 if (m_periodic_output_file_ptr
!= &cerr
) {
150 delete m_periodic_output_file_ptr
;
153 m_periodic_output_file_ptr
= new ofstream(filename
.c_str());
154 schedule(m_event
, g_system_ptr
->clockEdge(Cycles(1)));
158 Profiler::setPeriodicStatsInterval(int64_t period
)
160 cout
<< "Recording periodic statistics every " << m_stats_period
161 << " Ruby cycles" << endl
;
163 m_stats_period
= period
;
164 schedule(m_event
, g_system_ptr
->clockEdge(Cycles(1)));
168 Profiler::print(ostream
& out
) const
174 Profiler::printStats(ostream
& out
, bool short_stats
)
180 out
<< "Profiler Stats" << endl
;
181 out
<< "--------------" << endl
;
183 time_t real_time_current
= time(NULL
);
184 double seconds
= difftime(real_time_current
, m_real_time_start_time
);
185 double minutes
= seconds
/ 60.0;
186 double hours
= minutes
/ 60.0;
187 double days
= hours
/ 24.0;
188 Time ruby_cycles
= g_system_ptr
->getTime()-m_ruby_start
;
191 out
<< "Elapsed_time_in_seconds: " << seconds
<< endl
;
192 out
<< "Elapsed_time_in_minutes: " << minutes
<< endl
;
193 out
<< "Elapsed_time_in_hours: " << hours
<< endl
;
194 out
<< "Elapsed_time_in_days: " << days
<< endl
;
198 // print the virtual runtimes as well
201 seconds
= (vtime
.tms_utime
+ vtime
.tms_stime
) / 100.0;
202 minutes
= seconds
/ 60.0;
203 hours
= minutes
/ 60.0;
205 out
<< "Virtual_time_in_seconds: " << seconds
<< endl
;
206 out
<< "Virtual_time_in_minutes: " << minutes
<< endl
;
207 out
<< "Virtual_time_in_hours: " << hours
<< endl
;
208 out
<< "Virtual_time_in_days: " << days
<< endl
;
211 out
<< "Ruby_current_time: " << g_system_ptr
->getTime() << endl
;
212 out
<< "Ruby_start_time: " << m_ruby_start
<< endl
;
213 out
<< "Ruby_cycles: " << ruby_cycles
<< endl
;
217 out
<< "mbytes_resident: " << process_memory_resident() << endl
;
218 out
<< "mbytes_total: " << process_memory_total() << endl
;
219 if (process_memory_total() > 0) {
220 out
<< "resident_ratio: "
221 << process_memory_resident()/process_memory_total() << endl
;
226 vector
<int64_t> perProcCycleCount(m_num_of_sequencers
);
228 for (int i
= 0; i
< m_num_of_sequencers
; i
++) {
229 perProcCycleCount
[i
] =
230 g_system_ptr
->getTime() - m_cycles_executed_at_start
[i
] + 1;
231 // The +1 allows us to avoid division by zero
234 out
<< "ruby_cycles_executed: " << perProcCycleCount
<< endl
;
239 out
<< "Busy Controller Counts:" << endl
;
240 for (int i
= 0; i
< MachineType_NUM
; i
++) {
241 int size
= MachineType_base_count((MachineType
)i
);
242 for (int j
= 0; j
< size
; j
++) {
244 machID
.type
= (MachineType
)i
;
246 out
<< machID
<< ":" << m_busyControllerCount
[i
][j
] << " ";
247 if ((j
+ 1) % 8 == 0) {
255 out
<< "Busy Bank Count:" << m_busyBankCount
<< endl
;
258 out
<< "sequencer_requests_outstanding: "
259 << m_sequencer_requests
<< endl
;
264 out
<< "All Non-Zero Cycle Demand Cache Accesses" << endl
;
265 out
<< "----------------------------------------" << endl
;
266 out
<< "miss_latency: " << m_allMissLatencyHistogram
<< endl
;
267 for (int i
= 0; i
< m_missLatencyHistograms
.size(); i
++) {
268 if (m_missLatencyHistograms
[i
].size() > 0) {
269 out
<< "miss_latency_" << RubyRequestType(i
) << ": "
270 << m_missLatencyHistograms
[i
] << endl
;
273 for (int i
= 0; i
< m_machLatencyHistograms
.size(); i
++) {
274 if (m_machLatencyHistograms
[i
].size() > 0) {
275 out
<< "miss_latency_" << GenericMachineType(i
) << ": "
276 << m_machLatencyHistograms
[i
] << endl
;
280 out
<< "miss_latency_wCC_issue_to_initial_request: "
281 << m_wCCIssueToInitialRequestHistogram
<< endl
;
282 out
<< "miss_latency_wCC_initial_forward_request: "
283 << m_wCCInitialRequestToForwardRequestHistogram
<< endl
;
284 out
<< "miss_latency_wCC_forward_to_first_response: "
285 << m_wCCForwardRequestToFirstResponseHistogram
<< endl
;
286 out
<< "miss_latency_wCC_first_response_to_completion: "
287 << m_wCCFirstResponseToCompleteHistogram
<< endl
;
288 out
<< "imcomplete_wCC_Times: " << m_wCCIncompleteTimes
<< endl
;
289 out
<< "miss_latency_dir_issue_to_initial_request: "
290 << m_dirIssueToInitialRequestHistogram
<< endl
;
291 out
<< "miss_latency_dir_initial_forward_request: "
292 << m_dirInitialRequestToForwardRequestHistogram
<< endl
;
293 out
<< "miss_latency_dir_forward_to_first_response: "
294 << m_dirForwardRequestToFirstResponseHistogram
<< endl
;
295 out
<< "miss_latency_dir_first_response_to_completion: "
296 << m_dirFirstResponseToCompleteHistogram
<< endl
;
297 out
<< "imcomplete_dir_Times: " << m_dirIncompleteTimes
<< endl
;
299 for (int i
= 0; i
< m_missMachLatencyHistograms
.size(); i
++) {
300 for (int j
= 0; j
< m_missMachLatencyHistograms
[i
].size(); j
++) {
301 if (m_missMachLatencyHistograms
[i
][j
].size() > 0) {
302 out
<< "miss_latency_" << RubyRequestType(i
)
303 << "_" << GenericMachineType(j
) << ": "
304 << m_missMachLatencyHistograms
[i
][j
] << endl
;
311 out
<< "All Non-Zero Cycle SW Prefetch Requests" << endl
;
312 out
<< "------------------------------------" << endl
;
313 out
<< "prefetch_latency: " << m_allSWPrefetchLatencyHistogram
<< endl
;
314 for (int i
= 0; i
< m_SWPrefetchLatencyHistograms
.size(); i
++) {
315 if (m_SWPrefetchLatencyHistograms
[i
].size() > 0) {
316 out
<< "prefetch_latency_" << RubyRequestType(i
) << ": "
317 << m_SWPrefetchLatencyHistograms
[i
] << endl
;
320 for (int i
= 0; i
< m_SWPrefetchMachLatencyHistograms
.size(); i
++) {
321 if (m_SWPrefetchMachLatencyHistograms
[i
].size() > 0) {
322 out
<< "prefetch_latency_" << GenericMachineType(i
) << ": "
323 << m_SWPrefetchMachLatencyHistograms
[i
] << endl
;
326 out
<< "prefetch_latency_L2Miss:"
327 << m_SWPrefetchL2MissLatencyHistogram
<< endl
;
329 if (m_all_sharing_histogram
.size() > 0) {
330 out
<< "all_sharing: " << m_all_sharing_histogram
<< endl
;
331 out
<< "read_sharing: " << m_read_sharing_histogram
<< endl
;
332 out
<< "write_sharing: " << m_write_sharing_histogram
<< endl
;
334 out
<< "all_sharing_percent: ";
335 m_all_sharing_histogram
.printPercent(out
);
338 out
<< "read_sharing_percent: ";
339 m_read_sharing_histogram
.printPercent(out
);
342 out
<< "write_sharing_percent: ";
343 m_write_sharing_histogram
.printPercent(out
);
346 int64 total_miss
= m_cache_to_cache
+ m_memory_to_cache
;
347 out
<< "all_misses: " << total_miss
<< endl
;
348 out
<< "cache_to_cache_misses: " << m_cache_to_cache
<< endl
;
349 out
<< "memory_to_cache_misses: " << m_memory_to_cache
<< endl
;
350 out
<< "cache_to_cache_percent: "
351 << 100.0 * (double(m_cache_to_cache
) / double(total_miss
))
353 out
<< "memory_to_cache_percent: "
354 << 100.0 * (double(m_memory_to_cache
) / double(total_miss
))
359 if (m_outstanding_requests
.size() > 0) {
360 out
<< "outstanding_requests: ";
361 m_outstanding_requests
.printPercent(out
);
368 out
<< "Request vs. RubySystem State Profile" << endl
;
369 out
<< "--------------------------------" << endl
;
372 map
<string
, int>::const_iterator i
= m_requestProfileMap
.begin();
373 map
<string
, int>::const_iterator end
= m_requestProfileMap
.end();
374 for (; i
!= end
; ++i
) {
375 const string
&key
= i
->first
;
376 int count
= i
->second
;
378 double percent
= (100.0 * double(count
)) / double(m_requests
);
379 vector
<string
> items
;
380 tokenize(items
, key
, ':');
381 vector
<string
>::iterator j
= items
.begin();
382 vector
<string
>::iterator end
= items
.end();
383 for (; j
!= end
; ++i
)
384 out
<< setw(10) << *j
;
385 out
<< setw(11) << count
;
386 out
<< setw(14) << percent
<< endl
;
390 out
<< "filter_action: " << m_filter_action_histogram
<< endl
;
392 if (!m_all_instructions
) {
393 m_address_profiler_ptr
->printStats(out
);
396 if (m_all_instructions
) {
397 m_inst_profiler_ptr
->printStats(out
);
401 out
<< "Message Delayed Cycles" << endl
;
402 out
<< "----------------------" << endl
;
403 out
<< "Total_delay_cycles: " << m_delayedCyclesHistogram
<< endl
;
404 out
<< "Total_nonPF_delay_cycles: "
405 << m_delayedCyclesNonPFHistogram
<< endl
;
406 for (int i
= 0; i
< m_delayedCyclesVCHistograms
.size(); i
++) {
407 out
<< " virtual_network_" << i
<< "_delay_cycles: "
408 << m_delayedCyclesVCHistograms
[i
] << endl
;
411 printResourceUsage(out
);
416 Profiler::printResourceUsage(ostream
& out
) const
419 out
<< "Resource Usage" << endl
;
420 out
<< "--------------" << endl
;
422 int64_t pagesize
= getpagesize(); // page size in bytes
423 out
<< "page_size: " << pagesize
<< endl
;
426 getrusage (RUSAGE_SELF
, &usage
);
428 out
<< "user_time: " << usage
.ru_utime
.tv_sec
<< endl
;
429 out
<< "system_time: " << usage
.ru_stime
.tv_sec
<< endl
;
430 out
<< "page_reclaims: " << usage
.ru_minflt
<< endl
;
431 out
<< "page_faults: " << usage
.ru_majflt
<< endl
;
432 out
<< "swaps: " << usage
.ru_nswap
<< endl
;
433 out
<< "block_inputs: " << usage
.ru_inblock
<< endl
;
434 out
<< "block_outputs: " << usage
.ru_oublock
<< endl
;
438 Profiler::clearStats()
440 m_ruby_start
= g_system_ptr
->getTime();
441 m_real_time_start_time
= time(NULL
);
443 m_cycles_executed_at_start
.resize(m_num_of_sequencers
);
444 for (int i
= 0; i
< m_num_of_sequencers
; i
++) {
445 if (g_system_ptr
== NULL
) {
446 m_cycles_executed_at_start
[i
] = 0;
448 m_cycles_executed_at_start
[i
] = g_system_ptr
->getTime();
452 m_busyControllerCount
.resize(MachineType_NUM
); // all machines
453 for (int i
= 0; i
< MachineType_NUM
; i
++) {
454 int size
= MachineType_base_count((MachineType
)i
);
455 m_busyControllerCount
[i
].resize(size
);
456 for (int j
= 0; j
< size
; j
++) {
457 m_busyControllerCount
[i
][j
] = 0;
462 m_delayedCyclesHistogram
.clear();
463 m_delayedCyclesNonPFHistogram
.clear();
464 int size
= Network::getNumberOfVirtualNetworks();
465 m_delayedCyclesVCHistograms
.resize(size
);
466 for (int i
= 0; i
< size
; i
++) {
467 m_delayedCyclesVCHistograms
[i
].clear();
470 m_missLatencyHistograms
.resize(RubyRequestType_NUM
);
471 for (int i
= 0; i
< m_missLatencyHistograms
.size(); i
++) {
472 m_missLatencyHistograms
[i
].clear(200);
474 m_machLatencyHistograms
.resize(GenericMachineType_NUM
+1);
475 for (int i
= 0; i
< m_machLatencyHistograms
.size(); i
++) {
476 m_machLatencyHistograms
[i
].clear(200);
478 m_missMachLatencyHistograms
.resize(RubyRequestType_NUM
);
479 for (int i
= 0; i
< m_missLatencyHistograms
.size(); i
++) {
480 m_missMachLatencyHistograms
[i
].resize(GenericMachineType_NUM
+1);
481 for (int j
= 0; j
< m_missMachLatencyHistograms
[i
].size(); j
++) {
482 m_missMachLatencyHistograms
[i
][j
].clear(200);
485 m_allMissLatencyHistogram
.clear(200);
486 m_wCCIssueToInitialRequestHistogram
.clear(200);
487 m_wCCInitialRequestToForwardRequestHistogram
.clear(200);
488 m_wCCForwardRequestToFirstResponseHistogram
.clear(200);
489 m_wCCFirstResponseToCompleteHistogram
.clear(200);
490 m_wCCIncompleteTimes
= 0;
491 m_dirIssueToInitialRequestHistogram
.clear(200);
492 m_dirInitialRequestToForwardRequestHistogram
.clear(200);
493 m_dirForwardRequestToFirstResponseHistogram
.clear(200);
494 m_dirFirstResponseToCompleteHistogram
.clear(200);
495 m_dirIncompleteTimes
= 0;
497 m_SWPrefetchLatencyHistograms
.resize(RubyRequestType_NUM
);
498 for (int i
= 0; i
< m_SWPrefetchLatencyHistograms
.size(); i
++) {
499 m_SWPrefetchLatencyHistograms
[i
].clear(200);
501 m_SWPrefetchMachLatencyHistograms
.resize(GenericMachineType_NUM
+1);
502 for (int i
= 0; i
< m_SWPrefetchMachLatencyHistograms
.size(); i
++) {
503 m_SWPrefetchMachLatencyHistograms
[i
].clear(200);
505 m_allSWPrefetchLatencyHistogram
.clear(200);
507 m_sequencer_requests
.clear();
508 m_read_sharing_histogram
.clear();
509 m_write_sharing_histogram
.clear();
510 m_all_sharing_histogram
.clear();
511 m_cache_to_cache
= 0;
512 m_memory_to_cache
= 0;
515 m_requestProfileMap
.clear();
517 // count requests profiled
520 m_outstanding_requests
.clear();
521 m_outstanding_persistent_requests
.clear();
523 // Flush the prefetches through the system - used so that there
524 // are no outstanding requests after stats are cleared
525 //g_eventQueue_ptr->triggerAllEvents();
527 // update the start time
528 m_ruby_start
= g_system_ptr
->getTime();
532 Profiler::addAddressTraceSample(const RubyRequest
& msg
, NodeID id
)
534 if (msg
.getType() != RubyRequestType_IFETCH
) {
535 // Note: The following line should be commented out if you
536 // want to use the special profiling that is part of the GS320
539 // NOTE: Unless PROFILE_HOT_LINES is enabled, nothing will be
540 // profiled by the AddressProfiler
541 m_address_profiler_ptr
->
542 addTraceSample(msg
.getLineAddress(), msg
.getProgramCounter(),
543 msg
.getType(), msg
.getAccessMode(), id
, false);
548 Profiler::profileSharing(const Address
& addr
, AccessType type
,
549 NodeID requestor
, const Set
& sharers
,
552 Set
set_contacted(owner
);
553 if (type
== AccessType_Write
) {
554 set_contacted
.addSet(sharers
);
556 set_contacted
.remove(requestor
);
557 int number_contacted
= set_contacted
.count();
559 if (type
== AccessType_Write
) {
560 m_write_sharing_histogram
.add(number_contacted
);
562 m_read_sharing_histogram
.add(number_contacted
);
564 m_all_sharing_histogram
.add(number_contacted
);
566 if (number_contacted
== 0) {
574 Profiler::profileMsgDelay(uint32_t virtualNetwork
, Time delayCycles
)
576 assert(virtualNetwork
< m_delayedCyclesVCHistograms
.size());
577 m_delayedCyclesHistogram
.add(delayCycles
);
578 m_delayedCyclesVCHistograms
[virtualNetwork
].add(delayCycles
);
579 if (virtualNetwork
!= 0) {
580 m_delayedCyclesNonPFHistogram
.add(delayCycles
);
584 // profiles original cache requests including PUTs
586 Profiler::profileRequest(const string
& requestStr
)
590 // if it doesn't exist, conveniently, it will be created with the
591 // default value which is 0
592 m_requestProfileMap
[requestStr
]++;
596 Profiler::controllerBusy(MachineID machID
)
598 m_busyControllerCount
[(int)machID
.type
][(int)machID
.num
]++;
602 Profiler::profilePFWait(Time waitTime
)
604 m_prefetchWaitHistogram
.add(waitTime
);
613 // non-zero cycle demand request
615 Profiler::missLatency(Time cycles
,
616 RubyRequestType type
,
617 const GenericMachineType respondingMach
)
619 m_allMissLatencyHistogram
.add(cycles
);
620 m_missLatencyHistograms
[type
].add(cycles
);
621 m_machLatencyHistograms
[respondingMach
].add(cycles
);
622 m_missMachLatencyHistograms
[type
][respondingMach
].add(cycles
);
626 Profiler::missLatencyWcc(Time issuedTime
,
627 Time initialRequestTime
,
628 Time forwardRequestTime
,
629 Time firstResponseTime
,
632 if ((issuedTime
<= initialRequestTime
) &&
633 (initialRequestTime
<= forwardRequestTime
) &&
634 (forwardRequestTime
<= firstResponseTime
) &&
635 (firstResponseTime
<= completionTime
)) {
636 m_wCCIssueToInitialRequestHistogram
.add(initialRequestTime
- issuedTime
);
638 m_wCCInitialRequestToForwardRequestHistogram
.add(forwardRequestTime
-
641 m_wCCForwardRequestToFirstResponseHistogram
.add(firstResponseTime
-
644 m_wCCFirstResponseToCompleteHistogram
.add(completionTime
-
647 m_wCCIncompleteTimes
++;
652 Profiler::missLatencyDir(Time issuedTime
,
653 Time initialRequestTime
,
654 Time forwardRequestTime
,
655 Time firstResponseTime
,
658 if ((issuedTime
<= initialRequestTime
) &&
659 (initialRequestTime
<= forwardRequestTime
) &&
660 (forwardRequestTime
<= firstResponseTime
) &&
661 (firstResponseTime
<= completionTime
)) {
662 m_dirIssueToInitialRequestHistogram
.add(initialRequestTime
- issuedTime
);
664 m_dirInitialRequestToForwardRequestHistogram
.add(forwardRequestTime
-
667 m_dirForwardRequestToFirstResponseHistogram
.add(firstResponseTime
-
670 m_dirFirstResponseToCompleteHistogram
.add(completionTime
-
673 m_dirIncompleteTimes
++;
677 // non-zero cycle prefetch request
679 Profiler::swPrefetchLatency(Time cycles
,
680 RubyRequestType type
,
681 const GenericMachineType respondingMach
)
683 m_allSWPrefetchLatencyHistogram
.add(cycles
);
684 m_SWPrefetchLatencyHistograms
[type
].add(cycles
);
685 m_SWPrefetchMachLatencyHistograms
[respondingMach
].add(cycles
);
686 if (respondingMach
== GenericMachineType_Directory
||
687 respondingMach
== GenericMachineType_NUM
) {
688 m_SWPrefetchL2MissLatencyHistogram
.add(cycles
);
694 process_memory_total()
696 // 4kB page size, 1024*1024 bytes per MB,
697 const double MULTIPLIER
= 4096.0 / (1024.0 * 1024.0);
699 proc_file
.open("/proc/self/statm");
700 int total_size_in_pages
= 0;
701 int res_size_in_pages
= 0;
702 proc_file
>> total_size_in_pages
;
703 proc_file
>> res_size_in_pages
;
704 return double(total_size_in_pages
) * MULTIPLIER
; // size in megabytes
708 process_memory_resident()
710 // 4kB page size, 1024*1024 bytes per MB,
711 const double MULTIPLIER
= 4096.0 / (1024.0 * 1024.0);
713 proc_file
.open("/proc/self/statm");
714 int total_size_in_pages
= 0;
715 int res_size_in_pages
= 0;
716 proc_file
>> total_size_in_pages
;
717 proc_file
>> res_size_in_pages
;
718 return double(res_size_in_pages
) * MULTIPLIER
; // size in megabytes
722 Profiler::rubyWatch(int id
)
725 Address watch_address
= Address(tr
);
727 DPRINTFN("%7s %3s RUBY WATCH %d\n", g_system_ptr
->getTime(), id
,
730 // don't care about success or failure
731 m_watch_address_set
.insert(watch_address
);
735 Profiler::watchAddress(Address addr
)
737 return m_watch_address_set
.count(addr
) > 0;
741 RubyProfilerParams::create()
743 return new Profiler(this);