/// /// \author John Farrier /// /// \copyright Copyright 2015, 2016, 2017, 2018. 2019 John Farrier /// /// Licensed under the Apache License, Version 2.0 (the "License"); /// you may not use this file except in compliance with the License. /// You may obtain a copy of the License at /// /// http://www.apache.org/licenses/LICENSE-2.0 /// /// Unless required by applicable law or agreed to in writing, software /// distributed under the License is distributed on an "AS IS" BASIS, /// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. /// See the License for the specific language governing permissions and /// limitations under the License. /// #include #include #include #include #include #include #include #include #include using namespace celero; std::vector celero::BuildDistribution(uint64_t numberOfSamples, uint64_t iterationsPerSample) { std::vector measurements; while(numberOfSamples--) { // Dummy variable auto dummy = uint64_t(0); auto cps = iterationsPerSample; // Get the starting time. const auto startTime = celero::timer::GetSystemTime(); while(cps--) { celero::DoNotOptimizeAway(dummy++); } const auto endTime = celero::timer::GetSystemTime(); measurements.push_back(endTime - startTime); } return measurements; } void celero::RunDistribution(uint64_t intArgument) { std::vector series1Normalized(intArgument); std::vector series2Normalized(intArgument); std::vector series3Normalized(intArgument); std::vector series4Normalized(intArgument); const auto series1 = celero::BuildDistribution(intArgument, uint64_t(64)); const auto series2 = celero::BuildDistribution(intArgument, uint64_t(256)); const auto series3 = celero::BuildDistribution(intArgument, uint64_t(1024)); const auto series4 = celero::BuildDistribution(intArgument, uint64_t(4096)); if(series1.empty() == true || series2.empty() == true || series3.empty() == true || series4.empty() == true) { return; } std::array, 4> histograms; // Find the global max for all tests: auto maxVal = std::max(*(std::max_element(std::begin(series1), std::end(series1))), *(std::max_element(std::begin(series2), std::end(series2)))); maxVal = std::max(maxVal, *(std::max_element(std::begin(series3), std::end(series3)))); maxVal = std::max(maxVal, *(std::max_element(std::begin(series4), std::end(series4)))); // Find the global min for all tests: auto minVal = std::min(*(std::min_element(std::begin(series1), std::end(series1))), *(std::min_element(std::begin(series2), std::end(series2)))); minVal = std::min(minVal, *(std::min_element(std::begin(series3), std::end(series3)))); minVal = std::min(minVal, *(std::min_element(std::begin(series4), std::end(series4)))); // Normalize all vectors: auto normalize = [minVal, maxVal](uint64_t val) -> double { if(val >= minVal) { if(val <= maxVal) { const auto delta = maxVal - minVal; val -= minVal; return static_cast(val) / static_cast(delta); } return static_cast(maxVal); } return static_cast(minVal); }; std::transform(std::begin(series1), std::end(series1), std::begin(series1Normalized), [normalize](const uint64_t val) -> double { return normalize(val); }); std::transform(std::begin(series2), std::end(series2), std::begin(series2Normalized), [normalize](const uint64_t val) -> double { return normalize(val); }); std::transform(std::begin(series3), std::end(series3), std::begin(series3Normalized), [normalize](const uint64_t val) -> double { return normalize(val); }); std::transform(std::begin(series4), std::end(series4), std::begin(series4Normalized), [normalize](const uint64_t val) -> double { return normalize(val); }); // Build histograms of each of the series: std::for_each(std::begin(series1Normalized), std::end(series1Normalized), [&histograms](const double val) { histograms[0][static_cast(val * 1024)]++; }); std::for_each(std::begin(series2Normalized), std::end(series2Normalized), [&histograms](const double val) { histograms[1][static_cast(val * 1024)]++; }); std::for_each(std::begin(series3Normalized), std::end(series3Normalized), [&histograms](const double val) { histograms[2][static_cast(val * 1024)]++; }); std::for_each(std::begin(series4Normalized), std::end(series4Normalized), [&histograms](const double val) { histograms[3][static_cast(val * 1024)]++; }); // Find the maximum length of all histograms: auto maxLen = size_t(0); maxLen = std::max(maxLen, histograms[0].size()); maxLen = std::max(maxLen, histograms[1].size()); maxLen = std::max(maxLen, histograms[2].size()); maxLen = std::max(maxLen, histograms[3].size()); // Write out a CSV file that contains all four series: std::ofstream os; os.open("celeroDistribution.csv"); os << "64,,256,,1024,,4096,," << std::endl; for(size_t i = 0; i < maxLen; ++i) { for(size_t j = 0; j < histograms.size(); j++) { if(i < histograms[j].size()) { auto element = std::begin(histograms[j]); for(size_t k = 0; k < i; k++) { ++element; } os << element->first << "," << element->second << ","; } else { os << ",,"; } } os << std::endl; } os.close(); }