scons: Add '-Wl,--as-needed' to default LINKFLAGS
[gem5.git] / ext / mcpat / basic_components.cc
1 /*****************************************************************************
2 * McPAT
3 * SOFTWARE LICENSE AGREEMENT
4 * Copyright 2012 Hewlett-Packard Development Company, L.P.
5 * Copyright (c) 2010-2013 Advanced Micro Devices, Inc.
6 * All Rights Reserved
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met: redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer;
12 * redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution;
15 * neither the name of the copyright holders nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 ***************************************************************************/
32
33 #include <cassert>
34 #include <cmath>
35 #include <iostream>
36
37 #include "basic_components.h"
38 #include "cacheunit.h"
39 #include "common.h"
40
41 // Turn this to true to get debugging messages
42 bool McPATComponent::debug = false;
43
44 bool McPATComponent::opt_for_clk = true;
45 int McPATComponent::longer_channel_device = 0;
46 // Number of cycles per second, 2GHz = 2e9
47 double McPATComponent::target_core_clockrate = 2e9;
48 double McPATComponent::total_cycles = 0.0f;
49 double McPATComponent::execution_time = 0.0f;
50 int McPATComponent::physical_address_width = 0;
51 int McPATComponent::virtual_address_width = 0;
52 int McPATComponent::virtual_memory_page_size = 0;
53 int McPATComponent::data_path_width = 0;
54
55 void McPATOutput::reset() {
56 storage = 0.0;
57 area = 0.0;
58 peak_dynamic_power = 0.0;
59 subthreshold_leakage_power = 0.0;
60 gate_leakage_power = 0.0;
61 runtime_dynamic_energy = 0.0;
62 }
63
64 McPATOutput operator+(const McPATOutput &lhs, const McPATOutput &rhs) {
65 McPATOutput to_return;
66 to_return.storage = lhs.storage + rhs.storage;
67 to_return.area = lhs.area + rhs.area;
68 to_return.peak_dynamic_power = lhs.peak_dynamic_power +
69 rhs.peak_dynamic_power;
70 to_return.subthreshold_leakage_power = lhs.subthreshold_leakage_power +
71 rhs.subthreshold_leakage_power;
72 to_return.gate_leakage_power = lhs.gate_leakage_power +
73 rhs.gate_leakage_power;
74 to_return.runtime_dynamic_energy = lhs.runtime_dynamic_energy +
75 rhs.runtime_dynamic_energy;
76 return to_return;
77 }
78
79 void McPATOutput::operator+=(const McPATOutput &rhs) {
80 storage += rhs.storage;
81 area += rhs.area;
82 peak_dynamic_power += rhs.peak_dynamic_power;
83 subthreshold_leakage_power += rhs.subthreshold_leakage_power;
84 gate_leakage_power += rhs.gate_leakage_power;
85 runtime_dynamic_energy += rhs.runtime_dynamic_energy;
86 }
87
88 McPATComponent::McPATComponent()
89 : xml_data(NULL), name("") {
90 }
91
92 McPATComponent::McPATComponent(XMLNode* _xml_data)
93 : xml_data(_xml_data), name("") {
94 }
95
96 McPATComponent::McPATComponent(XMLNode* _xml_data,
97 InputParameter* _interface_ip)
98 : xml_data(_xml_data), interface_ip(*_interface_ip), name("") {
99 }
100
101 McPATComponent::~McPATComponent() {
102 }
103
104 void McPATComponent::recursiveInstantiate() {
105 if (debug) {
106 fprintf(stderr, "WARNING: Called recursiveInstantiate from %s, with ",
107 "'type' %s\n", name.c_str(), xml_data->getAttribute("type"));
108 }
109 int i;
110 int numChildren = xml_data->nChildNode("component");
111 for (i = 0; i < numChildren; i++ ) {
112 // For each child node of the system,
113 XMLNode* childXML = xml_data->getChildNodePtr("component", &i);
114 XMLCSTR type = childXML->getAttribute("type");
115
116 if (!type)
117 warnMissingComponentType(childXML->getAttribute("id"));
118
119 STRCMP(type, "Core")
120 warnIncompleteComponentType(type);
121 STRCMP(type, "CacheUnit")
122 children.push_back(new CacheUnit(childXML, &interface_ip));
123 STRCMP(type, "CacheController")
124 warnIncompleteComponentType(type);
125 STRCMP(type, "MemoryController")
126 warnIncompleteComponentType(type);
127 STRCMP(type, "Memory")
128 warnIncompleteComponentType(type);
129 STRCMP(type, "OnChipNetwork")
130 warnIncompleteComponentType(type);
131 STRCMP(type, "BusInterconnect")
132 warnIncompleteComponentType(type);
133 STRCMP(type, "Directory")
134 warnIncompleteComponentType(type);
135
136 else
137 warnUnrecognizedComponent(type);
138 }
139 }
140
141 void McPATComponent::computeArea() {
142 if (debug) {
143 fprintf(stderr, "WARNING: Called computeArea from %s, with 'type' ",
144 "%s\n", name.c_str(), xml_data->getAttribute("type"));
145 }
146
147 // TODO: This calculation is incorrect and is overwritten by computeEnergy
148 // Fix it up so that the values are available at the correct times
149 int i;
150 int numChildren = children.size();
151 area.set_area(0.0);
152 output_data.area = 0.0;
153 for (i = 0; i < numChildren; i++) {
154 children[i]->computeArea();
155 output_data.area += area.get_area();
156 }
157 }
158
159 void McPATComponent::computeEnergy() {
160 if (debug) {
161 fprintf(stderr, "WARNING: Called computeEnergy from %s, with 'type' ",
162 "%s\n", name.c_str(), xml_data->getAttribute("type"));
163 }
164
165 power.reset();
166 rt_power.reset();
167 memset(&output_data, 0, sizeof(McPATOutput));
168 int i;
169 int numChildren = children.size();
170 for (i = 0; i < numChildren; i++) {
171 children[i]->computeEnergy();
172 output_data += children[i]->output_data;
173 }
174 }
175
176 void McPATComponent::displayData(uint32_t indent, int plevel) {
177 if (debug) {
178 fprintf(stderr, "WARNING: Called displayData from %s, with 'type' ",
179 "%s\n", name.c_str(), xml_data->getAttribute("type"));
180 }
181
182 string indent_str(indent, ' ');
183 string indent_str_next(indent + 2, ' ');
184
185 double leakage_power = output_data.subthreshold_leakage_power +
186 output_data.gate_leakage_power;
187 double total_runtime_energy = output_data.runtime_dynamic_energy +
188 leakage_power * execution_time;
189 cout << indent_str << name << ":" << endl;
190 cout << indent_str_next << "Area = " << output_data.area << " mm^2"
191 << endl;
192 cout << indent_str_next << "Peak Dynamic Power = "
193 << output_data.peak_dynamic_power << " W" << endl;
194 cout << indent_str_next << "Subthreshold Leakage Power = "
195 << output_data.subthreshold_leakage_power << " W" << endl;
196 cout << indent_str_next << "Gate Leakage Power = "
197 << output_data.gate_leakage_power << " W" << endl;
198 cout << indent_str_next << "Runtime Dynamic Power = "
199 << (output_data.runtime_dynamic_energy / execution_time) << " W"
200 << endl;
201 cout << indent_str_next << "Runtime Dynamic Energy = "
202 << output_data.runtime_dynamic_energy << " J" << endl;
203 cout << indent_str_next << "Total Runtime Energy = "
204 << total_runtime_energy << " J" << endl;
205 cout << endl;
206
207 // Recursively print children
208 int i;
209 int numChildren = children.size();
210 for (i = 0; i < numChildren; i++) {
211 children[i]->displayData(indent + 4, plevel);
212 }
213 }
214
215 void McPATComponent::errorUnspecifiedParam(string param) {
216 fprintf(stderr, "ERROR: Parameter must be specified in %s: %s\n",
217 name.c_str(), param.c_str());
218 exit(1);
219 }
220
221 void McPATComponent::errorNonPositiveParam(string param) {
222 fprintf(stderr, "ERROR: Parameter must be positive in %s: %s\n",
223 name.c_str(), param.c_str());
224 exit(1);
225 }
226
227 void McPATComponent::warnUnrecognizedComponent(XMLCSTR component) {
228 fprintf(stderr, "WARNING: Component type not recognized in %s: %s\n",
229 name.c_str(), component);
230 }
231
232 void McPATComponent::warnUnrecognizedParam(XMLCSTR param) {
233 fprintf(stderr, "WARNING: Parameter not recognized in %s: %s\n",
234 name.c_str(), param);
235 }
236
237 void McPATComponent::warnUnrecognizedStat(XMLCSTR stat) {
238 fprintf(stderr, "WARNING: Statistic not recognized in %s: %s\n",
239 name.c_str(), stat);
240 }
241
242 void McPATComponent::warnIncompleteComponentType(XMLCSTR type) {
243 fprintf(stderr, " WARNING: %s handling not yet complete\n", type);
244 }
245
246 void McPATComponent::warnMissingComponentType(XMLCSTR id) {
247 if (id) {
248 fprintf(stderr,
249 "WARNING: Ignoring a component due to the missing type: %s\n",
250 id);
251 } else {
252 fprintf(stderr,
253 "WARNING: Ignoring a component in %s due to the missing type\n",
254 name.c_str());
255 }
256 }
257
258 void McPATComponent::warnMissingParamName(XMLCSTR id) {
259 if (id) {
260 fprintf(stderr,
261 "WARNING: Ignoring a parameter due to the missing name: %s\n",
262 id);
263 } else {
264 fprintf(stderr,
265 "WARNING: Ignoring a parameter in %s due to the missing name\n",
266 name.c_str());
267 }
268 }
269
270 void McPATComponent::warnMissingStatName(XMLCSTR id) {
271 if (id) {
272 fprintf(stderr,
273 "WARNING: Ignoring a statistic due to the missing name: %s\n",
274 id);
275 } else {
276 fprintf(stderr,
277 "WARNING: Ignoring a statistic in %s due to the missing name\n",
278 name.c_str());
279 }
280 }
281
282 double longer_channel_device_reduction(
283 enum Device_ty device_ty,
284 enum Core_type core_ty) {
285
286 double longer_channel_device_percentage_core;
287 double longer_channel_device_percentage_uncore;
288 double longer_channel_device_percentage_llc;
289
290 double long_channel_device_reduction;
291
292 longer_channel_device_percentage_llc = 1.0;
293 longer_channel_device_percentage_uncore = 0.82;
294 if (core_ty == OOO) {
295 //0.54 Xeon Tulsa //0.58 Nehelam
296 longer_channel_device_percentage_core = 0.56;
297 } else {
298 //0.8;//Niagara
299 longer_channel_device_percentage_core = 0.8;
300 }
301
302 if (device_ty == Core_device) {
303 long_channel_device_reduction =
304 (1 - longer_channel_device_percentage_core) +
305 longer_channel_device_percentage_core *
306 g_tp.peri_global.long_channel_leakage_reduction;
307 } else if (device_ty == Uncore_device) {
308 long_channel_device_reduction =
309 (1 - longer_channel_device_percentage_uncore) +
310 longer_channel_device_percentage_uncore *
311 g_tp.peri_global.long_channel_leakage_reduction;
312 } else if (device_ty == LLC_device) {
313 long_channel_device_reduction =
314 (1 - longer_channel_device_percentage_llc) +
315 longer_channel_device_percentage_llc *
316 g_tp.peri_global.long_channel_leakage_reduction;
317 } else {
318 cout << "ERROR: Unknown device category: " << device_ty << endl;
319 exit(0);
320 }
321
322 return long_channel_device_reduction;
323 }
324
325 statsComponents operator+(const statsComponents & x, const statsComponents & y) {
326 statsComponents z;
327
328 z.access = x.access + y.access;
329 z.hit = x.hit + y.hit;
330 z.miss = x.miss + y.miss;
331
332 return z;
333 }
334
335 statsComponents operator*(const statsComponents & x, double const * const y) {
336 statsComponents z;
337
338 z.access = x.access * y[0];
339 z.hit = x.hit * y[1];
340 z.miss = x.miss * y[2];
341
342 return z;
343 }
344
345 statsDef operator+(const statsDef & x, const statsDef & y) {
346 statsDef z;
347
348 z.readAc = x.readAc + y.readAc;
349 z.writeAc = x.writeAc + y.writeAc;
350 z.searchAc = x.searchAc + y.searchAc;
351 return z;
352 }
353
354 statsDef operator*(const statsDef & x, double const * const y) {
355 statsDef z;
356
357 z.readAc = x.readAc * y;
358 z.writeAc = x.writeAc * y;
359 z.searchAc = x.searchAc * y;
360 return z;
361 }