1 #include "Performance_Extraction.h"
6 Performance_Extraction performance_extraction("static_characterization.xml");
11 int get_current_time(CURRENT_TIME *current_time_ptr)
13 return clock_gettime(CLOCK_REALTIME, &(current_time_ptr->ts));
20 double sub_time(CURRENT_TIME *start_time_ptr, CURRENT_TIME *end_time_ptr)
22 CURRENT_TIME diff_time;
25 diff_time.ts.tv_sec = end_time_ptr->ts.tv_sec - start_time_ptr->ts.tv_sec;
26 diff_time.ts.tv_nsec = end_time_ptr->ts.tv_nsec - start_time_ptr->ts.tv_nsec;
27 time_ns = diff_time.ts.tv_sec * 1E+9 + diff_time.ts.tv_nsec;
36 Process_Performance::Process_Performance(const char *name)
38 strcpy(_process_name, name);
47 Process_Performance::~Process_Performance()
51 while (_head != NULL) {
62 const char *Process_Performance::get_name()
71 COMP_ENTRY *Process_Performance::get_head_entry()
80 COMP_ENTRY *Process_Performance::get_entry(int start_line, int end_line)
82 COMP_ENTRY *temp = NULL;
84 while (temp != NULL) {
85 if ((temp->start_line == start_line) && (temp->end_line == end_line)) {
98 COMP_ENTRY *Process_Performance::add_entry(int start_line, int end_line)
100 COMP_ENTRY *temp = NULL;
101 temp = get_entry(start_line, end_line);
103 temp = new COMP_ENTRY;
114 temp->start_line = start_line;
115 temp->end_line = end_line;
116 temp->total_computation_time = 0;
117 temp->called_times = 0;
127 int Process_Performance::set_entry(int start_line, int end_line,
128 CURRENT_TIME *start_time_ptr,
129 CURRENT_TIME *end_time_ptr)
133 double computation_time;
134 computation_time = sub_time(start_time_ptr, end_time_ptr);
135 temp = get_entry(start_line, end_line);
137 temp = add_entry(start_line, end_line);
140 temp->total_computation_time += computation_time;
141 temp->called_times++;
150 Performance_Extraction::Performance_Extraction(const char *chr_file_name)
152 strcpy(_chr_file_name, chr_file_name);
159 Performance_Extraction::~Performance_Extraction()
161 Process_Performance *process_performance_ptr;
163 #ifdef INCLUDE_PERFORMANCE
164 //strcpy(_processor_type, "DSP");
165 //add_to_xml_file(_chr_file_name);
166 //strcpy(_processor_type, "RISC");
167 //add_to_xml_file(_chr_file_name);
169 write_to_xml_file(_chr_file_name);
172 for (_iter_process_performance = _list_process_performance.begin();
173 _iter_process_performance != _list_process_performance.end();
174 _iter_process_performance++)
176 process_performance_ptr = *_iter_process_performance;
177 delete process_performance_ptr;
179 _list_process_performance.clear();
187 int Performance_Extraction::add_computation_performance(
188 const char *process_name, int start_line, int end_line,
189 CURRENT_TIME *start_time_ptr, CURRENT_TIME *end_time_ptr)
192 Process_Performance *process_performance_ptr;
194 process_performance_ptr = get_process_performance(process_name);
195 if (process_performance_ptr == NULL) {
196 process_performance_ptr = new Process_Performance(process_name);
197 _list_process_performance.push_back(process_performance_ptr);
200 process_performance_ptr->set_entry(start_line, end_line,
201 start_time_ptr, end_time_ptr);
210 Process_Performance *Performance_Extraction::get_process_performance(
211 const char *process_name)
213 Process_Performance *process_performance_ptr = NULL;
215 for (_iter_process_performance = _list_process_performance.begin();
216 _iter_process_performance != _list_process_performance.end();
217 _iter_process_performance++) {
218 process_performance_ptr = *_iter_process_performance;
219 if (strcmp(process_performance_ptr->get_name(), process_name) == 0) {
224 if (_iter_process_performance == _list_process_performance.end()) {
225 process_performance_ptr = NULL;
228 return process_performance_ptr;
233 * write performance data into XML file. (identical to add_to_xml_file()
234 * if file does not exist).
236 int Performance_Extraction::write_to_xml_file(const char *chr_file_name)
238 char start_line_str[NAME_LENGTH];
239 char end_line_str[NAME_LENGTH];
240 char computation_time_str[NAME_LENGTH];
241 double computation_time;
242 Process_Performance *process_performance_ptr;
243 COMP_ENTRY *comp_entry;
246 string text = "<?xml version=\"1.0\"?>\n<characterization>\n";
247 for (_iter_process_performance = _list_process_performance.begin();
248 _iter_process_performance != _list_process_performance.end();
249 _iter_process_performance++) {
250 process_performance_ptr = *_iter_process_performance;
252 text += " <process name=\"";
253 text += process_performance_ptr->get_name();
256 for (comp_entry = process_performance_ptr->get_head_entry();
258 comp_entry = comp_entry->next) {
259 sprintf(start_line_str, "%d", comp_entry->start_line);
260 sprintf(end_line_str, "%d", comp_entry->end_line);
262 //hack to eliminate the overhead of system call clock_gettime.
263 //computation_time is nano sec. To get cycles, need to mutiply
264 //by the frequency of cpu. result is in cycles.
265 computation_time = (comp_entry->total_computation_time
266 / comp_entry->called_times - SYS_OVERHEAD)
268 if (computation_time < 0) {
269 computation_time = 0;
271 sprintf(computation_time_str, "%.0f", computation_time);
273 text += " <computation start=\"";
274 text += start_line_str;
276 text += end_line_str;
278 text += " <processor type=\"DSP\" time=\"";
279 text += computation_time_str;
281 text += " <processor type=\"RISC\" time=\"";
282 text += computation_time_str;
284 text += " </computation>\n";
286 text += " </process>\n";
288 text += " <communication name=\"read\">\n";
289 text += " <processor type=\"DSP\" time=\"2\"/>\n";
290 text += " <processor type=\"RISC\" time=\"2\"/>\n";
291 text += " </communication>\n";
292 text += " <communication name=\"write\">\n";
293 text += " <processor type=\"DSP\" time=\"2\"/>\n";
294 text += " <processor type=\"RISC\" time=\"2\"/>\n";
295 text += " </communication>\n";
296 text += "</characterization>\n";
299 std::ofstream out(chr_file_name, ios::out);
301 printf("Cannot open file %s. Return.\n", chr_file_name);
304 out.write(text.c_str(), text.size());
311 * add performance data to existing XML file (or create new one if file
314 int Performance_Extraction::add_to_xml_file(const char *chr_file_name)
319 XMLNode process_node;
321 int computation_index = 0;
322 XMLNode processor_node;
326 Process_Performance *process_performance_ptr;
327 COMP_ENTRY *comp_entry;
329 char start_line_str[NAME_LENGTH];
330 char end_line_str[NAME_LENGTH];
331 char computation_time_str[NAME_LENGTH];
332 double computation_time;
334 file_node = XMLNode::parseFile(chr_file_name);
335 if (file_node.isEmpty()) {
336 file_node = XMLNode::createXMLTopNode("xml", TRUE);
337 file_node.addAttribute("version", "1.0");
338 root_node = file_node.addChild("characterization");
341 root_node = file_node.getChildNode();
342 if (root_node.isEmpty()) {
344 printf("Open characterization file error\n");
348 for (_iter_process_performance = _list_process_performance.begin();
349 _iter_process_performance != _list_process_performance.end();
350 _iter_process_performance++) {
351 process_performance_ptr = *_iter_process_performance;
353 printf("%s\n", process_performance_ptr->get_name());
355 process_node = root_node.getChildNodeWithAttribute(
356 "process", "name", process_performance_ptr->get_name());
357 if (process_node.isEmpty())
359 process_node = root_node.addChild("process");
360 process_node.addAttribute(
361 "name",process_performance_ptr->get_name());
364 for (comp_entry = process_performance_ptr->get_head_entry();
366 comp_entry = comp_entry->next) {
367 sprintf(start_line_str, "%d", comp_entry->start_line);
368 sprintf(end_line_str, "%d", comp_entry->end_line);
370 printf("%d %d\n", comp_entry->start_line, comp_entry->end_line);
372 /* Hack to eliminate the overhead of system call clock_gettime.
373 computation_time is nano sec. To get cycles, need to mutiply
374 by the frequency of cpu.
376 computation_time = (comp_entry->total_computation_time
377 / comp_entry->called_times - SYS_OVERHEAD)
380 if (computation_time < 0) {
381 computation_time = 0;
384 sprintf(computation_time_str, "%.0f", computation_time);
385 computation_index = 0;
386 comp_node = process_node.getChildNode("computation",
387 computation_index++);
388 while (!comp_node.isEmpty()) {
389 if (strcmp(comp_node.getAttribute("start"),start_line_str)==0
390 && strcmp(comp_node.getAttribute("end"),end_line_str)==0) {
394 comp_node = process_node.getChildNode("computation",
395 computation_index++);
398 if (comp_node.isEmpty()) {
399 comp_node = process_node.addChild("computation");
400 comp_node.addAttribute("start", start_line_str);
401 comp_node.addAttribute("end", end_line_str);
404 processor_node = comp_node.getChildNodeWithAttribute("processor", "type", _processor_type);
405 if (processor_node.isEmpty()) {
406 processor_node = comp_node.addChild("processor");
407 processor_node.addAttribute("type", _processor_type);
408 processor_node.addAttribute("time", computation_time_str);
413 read_node = root_node.getChildNodeWithAttribute("communication",
415 if (read_node.isEmpty()) {
416 read_node = root_node.addChild("communication");
417 read_node.addAttribute("name", "read");
420 processor_node = read_node.getChildNodeWithAttribute("processor",
423 if (processor_node.isEmpty()) {
424 processor_node = read_node.addChild("processor");
425 processor_node.addAttribute("type", _processor_type);
426 processor_node.addAttribute("time", "2");
429 write_node = root_node.getChildNodeWithAttribute("communication",
431 if (write_node.isEmpty()) {
432 write_node = root_node.addChild("communication");
433 write_node.addAttribute("name", "write");
436 processor_node = write_node.getChildNodeWithAttribute("processor",
439 if (processor_node.isEmpty()) {
440 processor_node = write_node.addChild("processor");
441 processor_node.addAttribute("type", _processor_type);
442 processor_node.addAttribute("time", "2");
445 file_node.writeToFile(chr_file_name);