#include "CpuTimeLogger.hpp"
#include "Constants.hpp"
#include "Debug.hpp"
#include <fstream>
namespace wren {
static const double MILLISECONDS_PER_CLOCK = 1.0 / (1e-3 * static_cast<double>(CLOCKS_PER_SEC));
CpuTimeLogger::CpuTimeLogger(int samplesPerMeasurement, int measurementsPerOutput, const std::string &name,
const std::string &filename, int maxPartialSamples) :
mMaxPartialSamples(maxPartialSamples),
mSamplesPerMeasurement(samplesPerMeasurement),
mMeasurementsPerOutput(measurementsPerOutput),
mPartialSamplesTaken(0),
mSamplesTaken(0),
mMeasurementsTaken(0),
mSamplingStarted(false),
mName(name),
mFilename(filename) {
mSamples.reserve(mSamplesPerMeasurement);
mPartialSamples.reserve(mMaxPartialSamples);
mSampleTimes.reserve(mSamplesPerMeasurement);
mMeasurements.reserve(mMeasurementsPerOutput);
}
void CpuTimeLogger::startSample() {
if (mMaxPartialSamples)
mSamplingStarted = true;
else
mSamples.push_back(Sample(clock()));
}
void CpuTimeLogger::startPartialSample() {
assert(mSamplingStarted);
assert(static_cast<int>(mPartialSamples.size()) < mMaxPartialSamples);
mPartialSamples.push_back(Sample(clock()));
}
void CpuTimeLogger::endPartialSample() {
assert(mSamplingStarted);
assert(mPartialSamples.back().mEnd == mPartialSamples.back().mStart);
mPartialSamples.back().mEnd = clock();
++mPartialSamplesTaken;
}
void CpuTimeLogger::endSample() {
if (!mMaxPartialSamples)
mSamples.back().mEnd = clock();
else {
mSamples.push_back(Sample(mPartialSamples.front().mStart));
for (int i = 0; i < mPartialSamplesTaken; ++i)
mSamples.back().mEnd += mPartialSamples[i].duration();
mPartialSamples.clear();
mPartialSamplesTaken = 0;
}
mSamplingStarted = false;
++mSamplesTaken;
if (mSamplesTaken == mSamplesPerMeasurement)
computeMeasurement();
}
void CpuTimeLogger::computeMeasurement() {
double mean = 0.0;
for (int i = 0; i < mSamplesPerMeasurement; ++i) {
mSampleTimes.push_back(static_cast<double>(mSamples[i].duration()) * MILLISECONDS_PER_CLOCK);
mean += mSampleTimes[i];
}
mean /= static_cast<double>(mSamplesPerMeasurement);
double variance = 0.0;
for (int i = 0; i < mSamplesPerMeasurement; ++i) {
variance += mSampleTimes[i] * mSampleTimes[i];
}
variance = (variance / static_cast<double>(mSamplesPerMeasurement)) - (mean * mean);
mMeasurements.push_back(Measurement(mean, variance));
++mMeasurementsTaken;
mSamples.clear();
mSampleTimes.clear();
mSamplesTaken = 0;
if (mMeasurementsTaken == mMeasurementsPerOutput) {
writeToFile();
mMeasurements.clear();
mMeasurementsTaken = 0;
}
}
void CpuTimeLogger::writeToFile() {
std::ofstream ofs;
ofs.open(mFilename.c_str(), std::ofstream::out | std::ofstream::app);
ofs << mName << ": writing " << mMeasurementsPerOutput << " measurements of " << mSamplesPerMeasurement << " samples"
<< std::endl;
for (int i = 0; i < mMeasurementsPerOutput; ++i)
ofs << "Measurement " << i << ": avg=" << mMeasurements[i].mMean << "ms, var=" << mMeasurements[i].mVariance << std::endl;
ofs.close();
}
}