@@ -22,24 +22,39 @@ void RModelProfiler::GenerateUtilityFunctions()
2222 auto &gc = fModel .fProfilerGC ;
2323
2424 // Generate PrintProfilingResults function
25- gc += " void PrintProfilingResults() const {\n " ;
25+ gc += " // generate code for printing operator results. By default order according to time (from higher to lower)\n " ;
26+ gc += " void PrintProfilingResults(bool order = true) const {\n " ;
2627 gc += " if (fProfilingResults.empty()) {\n " ;
2728 gc += " std::cout << \" No profiling results to display.\" << std::endl;\n " ;
2829 gc += " return;\n " ;
2930 gc += " }\n " ;
3031 gc += " \n " ;
32+ gc += " // compute summary statistics of profiling results and sort them in decreasing time\n " ;
33+ gc += " std::vector<std::tuple<std::string, double, double, int>> averageResults;\n " ;
3134 gc += " std::cout << \"\\ n\" << std::string(50, '=') << std::endl;\n " ;
3235 gc += " std::cout << \" AVERAGE PROFILING RESULTS\" << std::endl;\n " ;
3336 gc += " std::cout << std::string(50, '=') << std::endl;\n " ;
3437 gc += " for (const auto& op : fProfilingResults) {\n " ;
3538 gc += " double sum = 0.0;\n " ;
39+ gc += " double sum2 = 0.0;\n " ;
3640 gc += " for (double time : op.second) {\n " ;
3741 gc += " sum += time;\n " ;
42+ gc += " sum2 += time*time;\n " ;
3843 gc += " }\n " ;
3944 gc += " double average = sum / op.second.size();\n " ;
40- gc += " std::cout << \" \" << std::left << std::setw(20) << op.first\n " ;
41- gc += " << \" : \" << std::fixed << std::setprecision(6) << average << \" us\"\n " ;
42- gc += " << \" (over \" << op.second.size() << \" runs)\" << std::endl;\n " ;
45+ gc += " double stddev = std::sqrt(( sum2 - sum *average)/ (op.second.size()-1));\n " ;
46+ gc += " averageResults.push_back({op.first, average, stddev, op.second.size()});\n " ;
47+ gc += " }\n " ;
48+ gc += " \n " ;
49+ gc += " // sort average results in decreasing time\n " ;
50+ gc += " std::sort(averageResults.begin(), averageResults.end(),\n " ;
51+ gc += " []( std::tuple<std::string,double,double,int> a, std::tuple<std::string,double,double,int> b) {return std::get<1>(a) > std::get<1>(b); });\n " ;
52+ gc += " \n " ;
53+ gc += " for (const auto & r : averageResults) {\n " ;
54+ gc += " std::cout << \" \" << std::left << std::setw(20) << std::get<0>(r)\n " ;
55+ gc += " << \" : \" << std::fixed << std::setprecision(6) << std::get<1>(r) << \" +/- \" \n " ;
56+ gc += " << std::get<2>(r)/std::sqrt(std::get<3>(r)) << \" us\"\n " ;
57+ gc += " << \" (over \" << std::get<3>(r) << \" runs)\" << std::endl;\n " ;
4358 gc += " }\n " ;
4459 gc += " std::cout << std::string(50, '=') << \"\\ n\" << std::endl;\n " ;
4560 gc += " }\n " ;
@@ -71,7 +86,7 @@ void RModelProfiler::GenerateUtilityFunctions()
7186 gc += " }\n " ;
7287 gc += " \n " ;
7388
74- // Generate GetOpVariance function
89+ // Generate GetOpVariance function
7590 gc += " std::map<std::string, double> GetOpVariance() const {\n " ;
7691 gc += " if (fProfilingResults.empty()) {\n " ;
7792 gc += " return {};\n " ;
@@ -129,10 +144,10 @@ void RModelProfiler::Generate()
129144 const auto & op = fModel .fOperators [op_idx];
130145 gc += " // -- Profiling for operator " + op->name + " --\n " ;
131146 gc += " tp_start = std::chrono::steady_clock::now();\n\n " ;
132-
147+
133148 // Add the actual operator inference code
134149 gc += op->Generate (std::to_string (op_idx));
135-
150+
136151 // Add the code to stop the timer and store the result
137152 gc += " \n fProfilingResults[\" " + op->name + " \" ].push_back(\n " ;
138153 gc += " std::chrono::duration_cast<std::chrono::duration<double, std::micro>>(\n " ;
0 commit comments