Removed cout logging and put the wait time with load times

This commit is contained in:
Paul Ferrand 2020-01-14 01:07:15 +01:00
parent c3d5a06082
commit 24bd0d8119
4 changed files with 57 additions and 62 deletions

View file

@ -247,7 +247,6 @@ void sfz::FilePool::loadingThread() noexcept
threadsLoading++; threadsLoading++;
const auto loadStartTime = std::chrono::high_resolution_clock::now(); const auto loadStartTime = std::chrono::high_resolution_clock::now();
const auto waitDuration = loadStartTime - promise->creationTime; const auto waitDuration = loadStartTime - promise->creationTime;
logger.logFileWaitTime(waitDuration);
fs::path file { rootDirectory / std::string(promise->filename) }; fs::path file { rootDirectory / std::string(promise->filename) };
SndfileHandle sndFile(file.string().c_str()); SndfileHandle sndFile(file.string().c_str());
@ -259,7 +258,7 @@ void sfz::FilePool::loadingThread() noexcept
streamFromFile<float>(sndFile, frames, oversamplingFactor, promise->fileData, &promise->availableFrames); streamFromFile<float>(sndFile, frames, oversamplingFactor, promise->fileData, &promise->availableFrames);
promise->dataReady = true; promise->dataReady = true;
const auto loadDuration = std::chrono::high_resolution_clock::now() - loadStartTime; const auto loadDuration = std::chrono::high_resolution_clock::now() - loadStartTime;
logger.logFileLoadTime(loadDuration, frames, promise->filename); logger.logFileTime(waitDuration, loadDuration, frames, promise->filename);
threadsLoading--; threadsLoading--;

View file

@ -2,6 +2,7 @@
#include "absl/algorithm/container.h" #include "absl/algorithm/container.h"
#include "ghc/fs_std.hpp" #include "ghc/fs_std.hpp"
#include <iostream> #include <iostream>
#include <fstream>
#include <cmath> #include <cmath>
using namespace std::chrono_literals; using namespace std::chrono_literals;
@ -19,13 +20,16 @@ void printStatistics(std::vector<T>& data)
const auto sum = absl::c_accumulate(data, 0.0); const auto sum = absl::c_accumulate(data, 0.0);
const auto size = static_cast<T>(data.size()); const auto size = static_cast<T>(data.size());
const auto mean = sum / size; const auto mean = sum / size;
std::vector<T> squares;
absl::c_transform(data, std::back_inserter(squares), [mean](T x) { return x * x; });
const auto sumOfSquares = absl::c_accumulate(squares, 0.0);
const auto variance = sumOfSquares / (size - 1.0) - (mean * mean) / size / (size - 1.0);
std::cout << "Mean: " << mean << '\n'; std::cout << "Mean: " << mean << '\n';
std::cout << "Variance: " << variance << '\n'; if (data.size() > 1) {
std::cout << "(Biased) deviation: " << std::sqrt(variance) << '\n'; std::vector<T> squares;
absl::c_transform(data, std::back_inserter(squares), [mean](T x) { return x * x; });
const auto sumOfSquares = absl::c_accumulate(squares, 0.0);
const auto variance = sumOfSquares / (size - 1.0) - (mean * mean) / size / (size - 1.0);
std::cout << "Variance: " << variance << '\n';
std::cout << "(Biased) deviation: " << std::sqrt(variance) << '\n';
}
std::cout << "Maximum values:"; std::cout << "Maximum values:";
for (auto& value: maxValues) for (auto& value: maxValues)
std::cout << value << ' '; std::cout << value << ' ';
@ -37,66 +41,49 @@ sfz::Logger::~Logger()
keepRunning.clear(); keepRunning.clear();
loggingThread.join(); loggingThread.join();
if (!loadTimes.empty()) { if (!fileTimes.empty()) {
std::vector<double> loadTimesStats; fs::path loadLogPath{ fs::current_path() / "file_times.csv" };
std::vector<double> normLoadTimesStats; std::ofstream loadLogFile { loadLogPath.string() };
absl::c_transform(loadTimes, std::back_inserter(loadTimesStats), [](auto x) { return x.value.count(); }); loadLogFile << "WaitDuration,LoadDuration,FileSize,FileName" << '\n';
absl::c_transform(loadTimes, std::back_inserter(normLoadTimesStats), [](auto x) { for (auto& time: fileTimes)
if (x.fileSize == 0) loadLogFile << time.waitDuration.count() << ','
return x.value.count(); << time.loadDuration.count() << ','
<< time.fileSize << ','
return x.value.count() / static_cast<double>(x.fileSize); << time.filename << '\n';
});
std::cout << "\nFile load times" << '\n';
printStatistics(loadTimesStats);
std::cout << "\nNormalized file load times (per sample)" << '\n';
printStatistics(normLoadTimesStats);
}
if (!waitTimes.empty()) {
std::vector<double> waitTimesStats;
absl::c_transform(waitTimes, std::back_inserter(waitTimesStats), [](auto x) { return x.count(); });
std::cout << "\nWaiting times" << '\n';
printStatistics(waitTimesStats);
} }
if (!callbackTimes.empty()) { if (!callbackTimes.empty()) {
std::vector<double> callbackTimesStats; fs::path callbackLogPath{ fs::current_path() / "callback_times.csv" };
absl::c_transform(callbackTimes, std::back_inserter(callbackTimesStats), [](auto x) { return x.count(); }); std::ofstream callbackLogFile { callbackLogPath.string() };
std::cout << "\nCallback times" << '\n'; callbackLogFile << "Duration,NumVoices,NumSamples" << '\n';
printStatistics(callbackTimesStats); for (auto& time: callbackTimes)
callbackLogFile << time.duration.count() << ','
<< time.numVoices << ','
<< time.numSamples << '\n';
} }
} }
void sfz::Logger::logCallbackTime(std::chrono::duration<double> value) void sfz::Logger::logCallbackTime(std::chrono::duration<double> duration, int numVoices, int numSamples)
{ {
callbackTimeQueue.try_push(value); callbackTimeQueue.try_push<CallbackTime>({ duration, numVoices, numSamples });
} }
void sfz::Logger::logFileWaitTime(std::chrono::duration<double> value)
void sfz::Logger::logFileTime(std::chrono::duration<double> waitDuration, std::chrono::duration<double> loadDuration, uint32_t fileSize, absl::string_view filename)
{ {
fileWaitTimeQueue.try_push(value); fileTimeQueue.try_push<FileTime>({ waitDuration, loadDuration, fileSize, filename });
}
void sfz::Logger::logFileLoadTime(std::chrono::duration<double> value, uint32_t fileSize, absl::string_view filename)
{
FileLoadTime toPush { value, fileSize, filename };
fileLoadTimeQueue.try_push(toPush);
} }
void sfz::Logger::moveEvents() void sfz::Logger::moveEvents()
{ {
while(keepRunning.test_and_set()) { while(keepRunning.test_and_set()) {
std::chrono::duration<double> callbackTime; CallbackTime callbackTime;
while (callbackTimeQueue.try_pop(callbackTime)) while (callbackTimeQueue.try_pop(callbackTime))
callbackTimes.push_back(callbackTime); callbackTimes.push_back(callbackTime);
std::chrono::duration<double> waitTime; sfz::FileTime fileTime;
while (fileWaitTimeQueue.try_pop(waitTime)) while (fileTimeQueue.try_pop(fileTime))
waitTimes.push_back(waitTime); fileTimes.push_back(fileTime);
sfz::FileLoadTime loadTime;
while (fileLoadTimeQueue.try_pop(loadTime))
loadTimes.push_back(loadTime);
std::this_thread::sleep_for(50ms); std::this_thread::sleep_for(50ms);
} }

View file

@ -32,29 +32,36 @@
namespace sfz namespace sfz
{ {
struct FileLoadTime struct FileTime
{ {
std::chrono::duration<double> value; std::chrono::duration<double> waitDuration;
std::chrono::duration<double> loadDuration;
uint32_t fileSize; uint32_t fileSize;
absl::string_view filename; absl::string_view filename;
}; };
struct CallbackTime
{
std::chrono::duration<double> duration;
int numVoices;
int numSamples;
};
class Logger class Logger
{ {
public: public:
Logger() = default; Logger() = default;
~Logger(); ~Logger();
void logCallbackTime(std::chrono::duration<double> value); void logCallbackTime(std::chrono::duration<double> duration, int numVoices, int numSamples);
void logFileWaitTime(std::chrono::duration<double> value); void logFileTime(std::chrono::duration<double> waitDuration, std::chrono::duration<double> loadDuration, uint32_t fileSize, absl::string_view filename);
void logFileLoadTime(std::chrono::duration<double> value, uint32_t fileSize, absl::string_view filename);
private: private:
void moveEvents(); void moveEvents();
atomic_queue::AtomicQueue2<std::chrono::duration<double>, config::loggerQueueSize, true, true, false, true> callbackTimeQueue;
atomic_queue::AtomicQueue2<FileLoadTime, config::loggerQueueSize, true, true, false, true> fileLoadTimeQueue; atomic_queue::AtomicQueue2<CallbackTime, config::loggerQueueSize, true, true, false, true> callbackTimeQueue;
atomic_queue::AtomicQueue2<std::chrono::duration<double>, config::loggerQueueSize, true, true, false, true> fileWaitTimeQueue; atomic_queue::AtomicQueue2<FileTime, config::loggerQueueSize, true, true, false, true> fileTimeQueue;
std::vector<std::chrono::duration<double>> callbackTimes; std::vector<CallbackTime> callbackTimes;
std::vector<FileLoadTime> loadTimes; std::vector<FileTime> fileTimes;
std::vector<std::chrono::duration<double>> waitTimes;
std::atomic_flag keepRunning; std::atomic_flag keepRunning;
std::thread loggingThread { &Logger::moveEvents, this }; std::thread loggingThread { &Logger::moveEvents, this };
}; };

View file

@ -391,8 +391,10 @@ void sfz::Synth::renderBlock(AudioSpan<float> buffer) noexcept
return; return;
auto tempSpan = AudioSpan<float>(tempBuffer).first(buffer.getNumFrames()); auto tempSpan = AudioSpan<float>(tempBuffer).first(buffer.getNumFrames());
int numActiveVoices { 0 };
for (auto& voice : voices) { for (auto& voice : voices) {
if (!voice->isFree()) { if (!voice->isFree()) {
numActiveVoices++;
voice->renderBlock(tempSpan); voice->renderBlock(tempSpan);
buffer.add(tempSpan); buffer.add(tempSpan);
} }
@ -401,7 +403,7 @@ void sfz::Synth::renderBlock(AudioSpan<float> buffer) noexcept
buffer.applyGain(db2mag(volume)); buffer.applyGain(db2mag(volume));
const auto callbackDuration = std::chrono::high_resolution_clock::now() - callbackStartTime; const auto callbackDuration = std::chrono::high_resolution_clock::now() - callbackStartTime;
resources.logger.logCallbackTime(callbackDuration); resources.logger.logCallbackTime(callbackDuration, numActiveVoices, buffer.getNumFrames());
} }
void sfz::Synth::noteOn(int delay, int noteNumber, uint8_t velocity) noexcept void sfz::Synth::noteOn(int delay, int noteNumber, uint8_t velocity) noexcept