ruby: move stall and wakeup functions to AbstractController
[gem5.git] / src / mem / ruby / profiler / MemCntrlProfiler.cc
1 /*
2 * Copyright (c) 1999-2008 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 #include "mem/ruby/profiler/MemCntrlProfiler.hh"
30
31 using namespace std;
32
33 MemCntrlProfiler::MemCntrlProfiler(const string& description,
34 int banks_per_rank, int ranks_per_dimm, int dimms_per_channel)
35 {
36 m_description = description;
37 m_banks_per_rank = banks_per_rank;
38 m_ranks_per_dimm = ranks_per_dimm;
39 m_dimms_per_channel = dimms_per_channel;
40
41 int totalBanks = banks_per_rank * ranks_per_dimm * dimms_per_channel;
42 m_memBankCount.resize(totalBanks);
43
44 clearStats();
45 }
46
47 MemCntrlProfiler::~MemCntrlProfiler()
48 {
49 }
50
51 void
52 MemCntrlProfiler::printStats(ostream& out) const
53 {
54 if (!m_memReq && !m_memRefresh) {
55 out << "Memory Controller: " << m_description
56 << " no stats recorded." << endl
57 << endl
58 << endl;
59 return;
60 }
61
62 // if there's a memory controller at all
63 uint64 total_stalls = m_memInputQ + m_memBankQ + m_memWaitCycles;
64 double stallsPerReq = total_stalls * 1.0 / m_memReq;
65 out << "Memory controller: " << m_description << ":" << endl;
66
67 // does not include refreshes
68 out << " memory_total_requests: " << m_memReq << endl;
69 out << " memory_reads: " << m_memRead << endl;
70 out << " memory_writes: " << m_memWrite << endl;
71 out << " memory_refreshes: " << m_memRefresh << endl;
72 out << " memory_total_request_delays: " << total_stalls << endl;
73 out << " memory_delays_per_request: " << stallsPerReq << endl;
74 out << " memory_delays_in_input_queue: " << m_memInputQ << endl;
75 out << " memory_delays_behind_head_of_bank_queue: "
76 << m_memBankQ << endl;
77 out << " memory_delays_stalled_at_head_of_bank_queue: "
78 << m_memWaitCycles << endl;
79
80 // Note: The following "memory stalls" entries are a breakdown of
81 // the cycles which already showed up in m_memWaitCycles. The
82 // order is significant; it is the priority of attributing the
83 // cycles. For example, bank_busy is before arbitration because
84 // if the bank was busy, we didn't even check arbitration.
85 // Note: "not old enough" means that since we grouped waiting
86 // heads-of-queues into batches to avoid starvation, a request in
87 // a newer batch didn't try to arbitrate yet because there are
88 // older requests waiting.
89 out << " memory_stalls_for_bank_busy: " << m_memBankBusy << endl;
90 out << " memory_stalls_for_random_busy: " << m_memRandBusy << endl;
91 out << " memory_stalls_for_anti_starvation: " << m_memNotOld << endl;
92 out << " memory_stalls_for_arbitration: " << m_memArbWait << endl;
93 out << " memory_stalls_for_bus: " << m_memBusBusy << endl;
94 out << " memory_stalls_for_tfaw: " << m_memTfawBusy << endl;
95 out << " memory_stalls_for_read_write_turnaround: "
96 << m_memReadWriteBusy << endl;
97 out << " memory_stalls_for_read_read_turnaround: "
98 << m_memDataBusBusy << endl;
99 out << " accesses_per_bank: ";
100
101 for (int bank = 0; bank < m_memBankCount.size(); bank++) {
102 out << m_memBankCount[bank] << " ";
103 }
104 out << endl;
105 out << endl;
106 }
107
108 void
109 MemCntrlProfiler::clearStats()
110 {
111 m_memReq = 0;
112 m_memBankBusy = 0;
113 m_memBusBusy = 0;
114 m_memTfawBusy = 0;
115 m_memReadWriteBusy = 0;
116 m_memDataBusBusy = 0;
117 m_memRefresh = 0;
118 m_memRead = 0;
119 m_memWrite = 0;
120 m_memWaitCycles = 0;
121 m_memInputQ = 0;
122 m_memBankQ = 0;
123 m_memArbWait = 0;
124 m_memRandBusy = 0;
125 m_memNotOld = 0;
126
127 for (int bank = 0; bank < m_memBankCount.size(); bank++) {
128 m_memBankCount[bank] = 0;
129 }
130 }
131
132 void
133 MemCntrlProfiler::profileMemReq(int bank)
134 {
135 m_memReq++;
136 m_memBankCount[bank]++;
137 }
138
139 void
140 MemCntrlProfiler::profileMemBankBusy()
141 {
142 m_memBankBusy++;
143 }
144
145 void
146 MemCntrlProfiler::profileMemBusBusy()
147 {
148 m_memBusBusy++;
149 }
150
151 void
152 MemCntrlProfiler::profileMemReadWriteBusy()
153 {
154 m_memReadWriteBusy++;
155 }
156
157 void
158 MemCntrlProfiler::profileMemDataBusBusy()
159 {
160 m_memDataBusBusy++;
161 }
162
163 void
164 MemCntrlProfiler::profileMemTfawBusy()
165 {
166 m_memTfawBusy++;
167 }
168
169 void
170 MemCntrlProfiler::profileMemRefresh()
171 {
172 m_memRefresh++;
173 }
174
175 void
176 MemCntrlProfiler::profileMemRead()
177 {
178 m_memRead++;
179 }
180
181 void
182 MemCntrlProfiler::profileMemWrite()
183 {
184 m_memWrite++;
185 }
186
187 void
188 MemCntrlProfiler::profileMemWaitCycles(int cycles)
189 {
190 m_memWaitCycles += cycles;
191 }
192
193 void
194 MemCntrlProfiler::profileMemInputQ(int cycles)
195 {
196 m_memInputQ += cycles;
197 }
198
199 void
200 MemCntrlProfiler::profileMemBankQ(int cycles)
201 {
202 m_memBankQ += cycles;
203 }
204
205 void
206 MemCntrlProfiler::profileMemArbWait(int cycles)
207 {
208 m_memArbWait += cycles;
209 }
210
211 void
212 MemCntrlProfiler::profileMemRandBusy()
213 {
214 m_memRandBusy++;
215 }
216
217 void
218 MemCntrlProfiler::profileMemNotOld()
219 {
220 m_memNotOld++;
221 }
222
223