* Produces a GNUPlot graphable reverse CDF graph to stdout given a vector of * rdtsc time deltas a conversion factor for tsc to wall time seconds. * This is primarily used by NanoLog to visualize extreme tail latency behavior. * * \param timeDeltas * vector of rdtsc time differences * * \param cyclesPerSecond * conversion factor of tsc counts to seconds */
| 76 | * conversion factor of tsc counts to seconds |
| 77 | */ |
| 78 | void runRCDF(std::vector<uint64_t> timeDeltas, double cyclesPerSecond) { |
| 79 | printf("# Aggregating...\r\n"); |
| 80 | std::sort(timeDeltas.begin(), timeDeltas.end()); |
| 81 | printf("# Done; printing rcdf\r\n"); |
| 82 | printf("# Latency Percentage of Operations\r\n"); |
| 83 | |
| 84 | uint64_t sum = 0; |
| 85 | double boundary = 1.0e-10; // 1 decimal points into nanoseconds |
| 86 | uint64_t bound = PerfUtils::Cycles::fromSeconds(boundary, cyclesPerSecond); |
| 87 | double size = double(timeDeltas.size()); |
| 88 | |
| 89 | printf("%8.2lf %11.10lf\r\n", |
| 90 | 1e9*PerfUtils::Cycles::toSeconds(timeDeltas.front(), cyclesPerSecond), |
| 91 | 1.0); |
| 92 | |
| 93 | uint64_t lastPrinted = timeDeltas.front(); |
| 94 | for(uint64_t i = 1; i < timeDeltas.size(); ++i) { |
| 95 | sum += timeDeltas[i]; |
| 96 | if (timeDeltas[i] - lastPrinted > bound) { |
| 97 | printf("%8.2lf %11.10lf\r\n" |
| 98 | , 1e9*PerfUtils::Cycles::toSeconds(lastPrinted, cyclesPerSecond) |
| 99 | , 1.0 - double(i)/size); |
| 100 | lastPrinted = timeDeltas[i]; |
| 101 | } |
| 102 | } |
| 103 | |
| 104 | printf("%8.2lf %11.10lf\r\n", |
| 105 | 1e9*PerfUtils::Cycles::toSeconds(timeDeltas.back(), cyclesPerSecond), |
| 106 | 1/size); |
| 107 | |
| 108 | printf("\r\n# The mean was %0.2lf ns\r\n", |
| 109 | 1e9*PerfUtils::Cycles::toSeconds(sum/timeDeltas.size(), cyclesPerSecond)); |
| 110 | } |
| 111 | |
| 112 | /** |
| 113 | * Prints the usage information to stdout. |