166 lines
5.3 KiB
C++
166 lines
5.3 KiB
C++
///
|
|
/// \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 <celero/Distribution.h>
|
|
#include <celero/Print.h>
|
|
#include <celero/Utilities.h>
|
|
#include <algorithm>
|
|
#include <array>
|
|
#include <cmath>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <map>
|
|
|
|
using namespace celero;
|
|
|
|
std::vector<uint64_t> celero::BuildDistribution(uint64_t numberOfSamples, uint64_t iterationsPerSample)
|
|
{
|
|
std::vector<uint64_t> 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<double> series1Normalized(intArgument);
|
|
std::vector<double> series2Normalized(intArgument);
|
|
std::vector<double> series3Normalized(intArgument);
|
|
std::vector<double> 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<std::map<double, uint64_t>, 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<double>(val) / static_cast<double>(delta);
|
|
}
|
|
|
|
return static_cast<double>(maxVal);
|
|
}
|
|
|
|
return static_cast<double>(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<int>(val * 1024)]++; });
|
|
|
|
std::for_each(std::begin(series2Normalized), std::end(series2Normalized),
|
|
[&histograms](const double val) { histograms[1][static_cast<int>(val * 1024)]++; });
|
|
|
|
std::for_each(std::begin(series3Normalized), std::end(series3Normalized),
|
|
[&histograms](const double val) { histograms[2][static_cast<int>(val * 1024)]++; });
|
|
|
|
std::for_each(std::begin(series4Normalized), std::end(series4Normalized),
|
|
[&histograms](const double val) { histograms[3][static_cast<int>(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();
|
|
}
|