Removed cout logging and put the wait time with load times
This commit is contained in:
parent
c3d5a06082
commit
24bd0d8119
4 changed files with 57 additions and 62 deletions
|
|
@ -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--;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 };
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue