| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /*************************************** | ||
| 2 | Auteur : Pierre Aubert | ||
| 3 | Mail : pierre.aubert@lapp.in2p3.fr | ||
| 4 | Licence : CeCILL-C | ||
| 5 | ****************************************/ | ||
| 6 | |||
| 7 | #include <iostream> | ||
| 8 | #include <algorithm> | ||
| 9 | #include <fstream> | ||
| 10 | |||
| 11 | #include "PFunctionTimer.h" | ||
| 12 | |||
| 13 | ///Default constructor of PFunctionTimer | ||
| 14 | /** @param nbMeasure : number of performance measures we want on this function | ||
| 15 | * @param nbElement : number of elements the function is computing (supposed to be constant for all the performance tests) | ||
| 16 | */ | ||
| 17 | 1 | PFunctionTimer::PFunctionTimer(size_t nbMeasure, size_t nbElement){ | |
| 18 |
1/1✓ Branch 0 (4→5) taken 1 times.
|
1 | initialisationPFunctionTimer(nbMeasure, nbElement); |
| 19 | 1 | } | |
| 20 | |||
| 21 | ///Copy constructor of PFunctionTimer | ||
| 22 | /** @param other : class to copy | ||
| 23 | */ | ||
| 24 | ✗ | PFunctionTimer::PFunctionTimer(const PFunctionTimer & other){ | |
| 25 | ✗ | copyPFunctionTimer(other); | |
| 26 | ✗ | } | |
| 27 | |||
| 28 | ///Destructor of PFunctionTimer | ||
| 29 | 1 | PFunctionTimer::~PFunctionTimer(){ | |
| 30 | |||
| 31 | 1 | } | |
| 32 | |||
| 33 | ///Definition of equal operator of PFunctionTimer | ||
| 34 | /** @param other : class to copy | ||
| 35 | * @return copied class | ||
| 36 | */ | ||
| 37 | ✗ | PFunctionTimer & PFunctionTimer::operator = (const PFunctionTimer & other){ | |
| 38 | ✗ | copyPFunctionTimer(other); | |
| 39 | ✗ | return *this; | |
| 40 | } | ||
| 41 | |||
| 42 | ///Set the number of elements to consider for the function timing | ||
| 43 | /** @param nbElement : number of elements the function is computing (supposed to be constant for all the performance tests) | ||
| 44 | */ | ||
| 45 | 1 | void PFunctionTimer::setNbElement(size_t nbElement){ | |
| 46 | 1 | p_nbElement = nbElement; | |
| 47 | 1 | } | |
| 48 | |||
| 49 | ///Resize the number of possible measures | ||
| 50 | /** @param nbMeasure : number of performance measures we want on this function | ||
| 51 | */ | ||
| 52 | 1 | void PFunctionTimer::resize(size_t nbMeasure){ | |
| 53 | 1 | p_nbMeasure = nbMeasure; | |
| 54 | 1 | p_vecEllapsedTimeNs.resize(p_nbMeasure); | |
| 55 | 1 | p_vecEllapsedTimeCycle.resize(p_nbMeasure); | |
| 56 | 1 | } | |
| 57 | |||
| 58 | ///Save a vector of values into a toml stream | ||
| 59 | /** @param[out] fs : file stream to be updated | ||
| 60 | * @param vecValue : vector of values to be saved | ||
| 61 | * @param tableName : name of the attribute | ||
| 62 | * @param nbElement : number of commputed elements for ns/el and cy/el (otherwise 1) | ||
| 63 | */ | ||
| 64 | 5 | void phoenix_vectorToToml(std::ofstream & fs, const std::vector<double> & vecValue, const std::string & tableName, double nbElement){ | |
| 65 |
1/1✓ Branch 0 (4→5) taken 5 times.
|
5 | std::string comma(""); |
| 66 |
3/3✓ Branch 0 (6→7) taken 5 times.
✓ Branch 2 (7→8) taken 5 times.
✓ Branch 4 (8→9) taken 5 times.
|
5 | fs << tableName << " = [" << std::endl; |
| 67 |
2/2✓ Branch 0 (26→11) taken 500 times.
✓ Branch 1 (26→27) taken 5 times.
|
510 | for(double value : vecValue){ |
| 68 |
3/3✓ Branch 0 (13→14) taken 500 times.
✓ Branch 2 (14→15) taken 500 times.
✓ Branch 4 (15→16) taken 500 times.
|
500 | fs << comma << "\t" << value/nbElement; |
| 69 |
1/1✓ Branch 0 (16→17) taken 500 times.
|
500 | comma = ",\n"; |
| 70 | } | ||
| 71 |
2/2✓ Branch 0 (27→28) taken 5 times.
✓ Branch 2 (28→29) taken 5 times.
|
5 | fs << "\n]" << std::endl; |
| 72 | 5 | } | |
| 73 | |||
| 74 | ///Save the performance of the function in a file | ||
| 75 | /** @param fileName : name of the file to be saved with our function performances | ||
| 76 | * @return true on success, false otherwise | ||
| 77 | */ | ||
| 78 | 1 | bool PFunctionTimer::savePerf(const std::string & fileName) const{ | |
| 79 |
3/6✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→6) not taken.
✗ Branch 2 (5→6) not taken.
✓ Branch 3 (5→7) taken 1 times.
✗ Branch 4 (8→9) not taken.
✓ Branch 5 (8→14) taken 1 times.
|
1 | if(p_vecEllapsedTimeCycle.size() == 0lu || p_vecEllapsedTimeNs.size() == 0lu){ |
| 80 | ✗ | std::cerr << "PFunctionTimer::savePerf : cannot save empty vector in file '"<<fileName<<"'" << std::endl; | |
| 81 | ✗ | return false; | |
| 82 | } | ||
| 83 |
1/1✓ Branch 0 (14→15) taken 1 times.
|
1 | std::ofstream fs; |
| 84 |
1/1✓ Branch 0 (15→16) taken 1 times.
|
1 | fs.open(fileName); |
| 85 |
1/2✗ Branch 0 (17→18) not taken.
✓ Branch 1 (17→23) taken 1 times.
|
1 | if(!fs.is_open()){ |
| 86 | ✗ | std::cerr << "PFunctionTimer::savePerf : cannot save file '"<<fileName<<"'" << std::endl; | |
| 87 | ✗ | return false; | |
| 88 | } | ||
| 89 |
2/2✓ Branch 0 (23→24) taken 1 times.
✓ Branch 2 (24→25) taken 1 times.
|
1 | fs << "#Global performances" << std::endl; |
| 90 |
2/2✓ Branch 0 (25→26) taken 1 times.
✓ Branch 2 (26→27) taken 1 times.
|
1 | fs << "[Performance]" << std::endl; |
| 91 |
3/3✓ Branch 0 (27→28) taken 1 times.
✓ Branch 2 (28→29) taken 1 times.
✓ Branch 4 (29→30) taken 1 times.
|
1 | fs << "nb_element = " << p_nbElement << std::endl; |
| 92 |
3/3✓ Branch 0 (30→31) taken 1 times.
✓ Branch 2 (31→32) taken 1 times.
✓ Branch 4 (32→33) taken 1 times.
|
1 | fs << "nb_measure = " << p_nbMeasure << std::endl; |
| 93 |
1/1✓ Branch 0 (33→34) taken 1 times.
|
1 | fs << std::endl; |
| 94 | 1 | std::vector<double> orderPerfNs, orderPerfCy; | |
| 95 |
1/1✓ Branch 0 (36→37) taken 1 times.
|
1 | getSortedPerf(orderPerfNs, orderPerfCy); |
| 96 | |||
| 97 | //Let's save the best performances | ||
| 98 |
2/2✓ Branch 0 (39→40) taken 1 times.
✓ Branch 2 (40→41) taken 1 times.
|
2 | saveQuantilePerf(fs, orderPerfNs, orderPerfCy, "best", 0lu); |
| 99 | //Let's save the median performances | ||
| 100 |
2/2✓ Branch 0 (45→46) taken 1 times.
✓ Branch 2 (46→47) taken 1 times.
|
1 | saveQuantilePerf(fs, orderPerfNs, orderPerfCy, "median", p_nbMeasure/2lu); |
| 101 | |||
| 102 |
1/1✓ Branch 0 (49→50) taken 1 times.
|
1 | fs << std::endl; |
| 103 |
2/2✓ Branch 0 (50→51) taken 1 times.
✓ Branch 2 (51→52) taken 1 times.
|
1 | fs << "#Detailed performances" << std::endl; |
| 104 |
2/2✓ Branch 0 (52→53) taken 1 times.
✓ Branch 2 (53→54) taken 1 times.
|
1 | fs << "[Detail]" << std::endl; |
| 105 |
2/2✓ Branch 0 (56→57) taken 1 times.
✓ Branch 2 (57→58) taken 1 times.
|
2 | phoenix_vectorToToml(fs, p_vecEllapsedTimeNs, "measure_nanosecond", 1.0); |
| 106 |
2/2✓ Branch 0 (62→63) taken 1 times.
✓ Branch 2 (63→64) taken 1 times.
|
2 | phoenix_vectorToToml(fs, p_vecEllapsedTimeCycle, "measure_cycles", 1.0); |
| 107 |
2/2✓ Branch 0 (68→69) taken 1 times.
✓ Branch 2 (69→70) taken 1 times.
|
2 | phoenix_vectorToToml(fs, p_vecEllapsedTimeNs, "measure_nanosecond_per_element", (double)p_nbElement); |
| 108 |
2/2✓ Branch 0 (74→75) taken 1 times.
✓ Branch 2 (75→76) taken 1 times.
|
2 | phoenix_vectorToToml(fs, p_vecEllapsedTimeCycle, "measure_cycles_per_element", (double)p_nbElement); |
| 109 | //Let's save the ratio of cycles over nanoseconds | ||
| 110 |
1/1✓ Branch 0 (81→82) taken 1 times.
|
2 | std::vector<double> vecCyPerNs(p_vecEllapsedTimeCycle.size()); |
| 111 | 1 | std::transform(p_vecEllapsedTimeCycle.begin(), p_vecEllapsedTimeCycle.end(), | |
| 112 | p_vecEllapsedTimeNs.begin(), vecCyPerNs.begin(), | ||
| 113 | 100 | [](double cy, double ns){ | |
| 114 | 100 | return cy/ns; | |
| 115 | }); | ||
| 116 |
2/2✓ Branch 0 (90→91) taken 1 times.
✓ Branch 2 (91→92) taken 1 times.
|
1 | phoenix_vectorToToml(fs, vecCyPerNs, "cycles_over_nanosecond", 1.0); |
| 117 |
1/1✓ Branch 0 (94→95) taken 1 times.
|
1 | fs.close(); |
| 118 | 1 | return true; | |
| 119 | 1 | } | |
| 120 | |||
| 121 | ///Get the ordered performances | ||
| 122 | /** @param[out] orderPerfNs : sorted performance in nanoseconds | ||
| 123 | * @param[out] orderPerfCy : sorted performance in cycles | ||
| 124 | */ | ||
| 125 | 1 | void PFunctionTimer::getSortedPerf(std::vector<double> & orderPerfNs, std::vector<double> & orderPerfCy) const{ | |
| 126 | 1 | orderPerfNs = p_vecEllapsedTimeNs; | |
| 127 | 1 | orderPerfCy = p_vecEllapsedTimeCycle; | |
| 128 | 1 | std::sort(orderPerfNs.begin(), orderPerfNs.end()); | |
| 129 | 1 | std::sort(orderPerfCy.begin(), orderPerfCy.end()); | |
| 130 | 1 | } | |
| 131 | |||
| 132 | ///Get the number of elements computed in the performance test | ||
| 133 | /** @return number of elements computed in the performance test | ||
| 134 | */ | ||
| 135 | ✗ | size_t PFunctionTimer::getNbElement() const{ | |
| 136 | ✗ | return p_nbElement; | |
| 137 | } | ||
| 138 | |||
| 139 | ///Copy function of PFunctionTimer | ||
| 140 | /** @param other : class to copy | ||
| 141 | */ | ||
| 142 | ✗ | void PFunctionTimer::copyPFunctionTimer(const PFunctionTimer & other){ | |
| 143 | ✗ | p_nbMeasure = other.p_nbMeasure; | |
| 144 | ✗ | p_nbElement = other.p_nbElement; | |
| 145 | ✗ | p_vecEllapsedTimeNs = other.p_vecEllapsedTimeNs; | |
| 146 | ✗ | p_vecEllapsedTimeCycle = other.p_vecEllapsedTimeCycle; | |
| 147 | ✗ | } | |
| 148 | |||
| 149 | ///Initialisation function of the class PFunctionTimer | ||
| 150 | /** @param nbMeasure : number of performance measures we want on this function | ||
| 151 | * @param nbElement : number of elements the function is computing (supposed to be constant for all the performance tests) | ||
| 152 | */ | ||
| 153 | 1 | void PFunctionTimer::initialisationPFunctionTimer(size_t nbMeasure, size_t nbElement){ | |
| 154 | 1 | setNbElement(nbElement); | |
| 155 | 1 | resize(nbMeasure); | |
| 156 | 1 | } | |
| 157 | |||
| 158 | ///Save the performance of the given quantile | ||
| 159 | /** @param[out] fs : stream to be updated | ||
| 160 | * @param orderPerfNs : ordered performances in nanoseconds | ||
| 161 | * @param orderPerfCy : ordered performances in cycles | ||
| 162 | * @param name : name of the variable | ||
| 163 | * @param valueIndex : index of the value in the tables | ||
| 164 | */ | ||
| 165 | 2 | void PFunctionTimer::saveQuantilePerf(std::ofstream & fs, const std::vector<double> & orderPerfNs, const std::vector<double> & orderPerfCy, | |
| 166 | const std::string & name, size_t valueIndex) const | ||
| 167 | { | ||
| 168 | 2 | fs << "#"<<name<<" performance in nano seconds" << std::endl; | |
| 169 | 2 | fs << name << "_nanosecond = " << orderPerfNs[valueIndex] << std::endl; | |
| 170 | 2 | fs << "#Best performance in cycles" << std::endl; | |
| 171 | 2 | fs << name << "_cycle = " << orderPerfCy[valueIndex] << std::endl; | |
| 172 | 2 | fs << std::endl; | |
| 173 | 2 | fs << "#"<<name<<" performance in nano seconds per elements" << std::endl; | |
| 174 | 2 | fs << name << "_nanosecond_per_element = " << orderPerfNs[valueIndex]/p_nbElement << std::endl; | |
| 175 | 2 | fs << "#"<<name<<" performance in cycles per elements" << std::endl; | |
| 176 | 2 | fs << name << "_cycle_per_element = " << orderPerfCy[valueIndex]/p_nbElement << std::endl; | |
| 177 | 2 | fs << "#"<<name<<" performance in Giga Elements per second" << std::endl; | |
| 178 | 2 | fs << name << "_giga_element_per_second = " << p_nbElement/orderPerfNs[valueIndex] << std::endl; | |
| 179 | 2 | fs << std::endl; | |
| 180 | 2 | } | |
| 181 | |||
| 182 | |||
| 183 | |||
| 184 |