14#include "../../../tracktion_core/utilities/tracktion_Benchmark.h"
15#include "../../playback/graph/tracktion_TracktionEngineNode.h"
16#include "../../playback/graph/tracktion_TracktionNodePlayer.h"
17#include "../../playback/graph/tracktion_MultiThreadedNodePlayer.h"
19namespace tracktion {
inline namespace engine
22namespace benchmark_utilities
25 enum class MultiThreaded { no, yes };
27 enum class LockFree { no, yes };
29 enum class PoolMemoryAllocations { no, yes };
31 enum class ShareNodeMemory { no, yes };
38 MultiThreaded isMultiThreaded;
41 PoolMemoryAllocations poolMemoryAllocations = PoolMemoryAllocations::no;
42 ShareNodeMemory shareNodeMemory = ShareNodeMemory::no;
47 using namespace tracktion::graph;
48 auto s = graph::test_utilities::getDescription (opts.testSetup)
49 +
juce::String (opts.isMultiThreaded == MultiThreaded::yes ?
", MT" :
", ST");
51 if (opts.isMultiThreaded == MultiThreaded::yes && opts.isLockFree == LockFree::yes)
54 if (opts.poolMemoryAllocations == PoolMemoryAllocations::yes)
55 s <<
", pooled-memory";
57 if (opts.shareNodeMemory == ShareNodeMemory::yes)
58 s <<
", share-node-memory";
60 if (opts.isMultiThreaded == MultiThreaded::yes)
61 s <<
", " + graph::test_utilities::getName (opts.poolType);
68 double sampleRate,
int blockSize)
71 params.sampleRate = sampleRate;
72 params.blockSize = blockSize;
73 params.forRendering =
true;
77 template<
typename NodePlayerType>
81 MultiThreaded isMultiThreaded)
84 ut.
beginTest (editName +
" - preparing: " + description);
86 if (isMultiThreaded == MultiThreaded::no)
87 testContext.getNodePlayer().setNumThreads (0);
89 testContext.setPlayHead (&playHeadState.playHead);
93 ut.
beginTest (editName +
" - memory use: " + description);
95 const auto nodes = tracktion::graph::getNodes (testContext.getNode(), tracktion::graph::VertexOrdering::postordering);
96 const auto sizeInBytes = tracktion::graph::test_utilities::getMemoryUsage (nodes);
99 bmr.totalSeconds =
static_cast<double> (sizeInBytes);
103 std::cout <<
"Num nodes: " << nodes.size() <<
"\n";
108 ut.
beginTest (editName +
" - rendering: " + description);
110 auto result = testContext.processAll();
111 const auto stats = testContext.getStatisticsAndReset();
114 (editName +
": rendering").toStdString(),
115 description.toStdString()),
118 std::cout << sw.getDescription() <<
"\n";
119 std::cout << stats.toString (testContext.getPerformanceMeasurement().
getName()) <<
"\n";
122 ut.
beginTest (editName +
" - destroying: " + description);
130 inline void renderEdit (
juce::UnitTest& ut, BenchmarkOptions opts)
132 assert (opts.edit !=
nullptr);
133 assert (opts.shareNodeMemory == ShareNodeMemory::no || opts.isLockFree == LockFree::yes);
134 const auto description = getDescription (opts);
138 ProcessState processState { playHeadState, opts.edit->tempoSequence };
141 ut.
beginTest (opts.editName +
" - building: " + description);
143 auto node = createNode (*opts.edit, processState, opts.testSetup.sampleRate, opts.testSetup.blockSize);
145 ut.
expect (node !=
nullptr);
148 if (opts.isLockFree == LockFree::yes)
152 processState, opts.testSetup.sampleRate, opts.testSetup.blockSize,
153 tracktion::graph::getPoolCreatorFunction (opts.poolType)),
154 opts.testSetup, 2, opts.edit->getLength().inSeconds(),
false);
156 if (opts.poolMemoryAllocations == PoolMemoryAllocations::yes)
157 testContext.getNodePlayer().enablePooledMemoryAllocations (
true);
159 if (opts.shareNodeMemory == ShareNodeMemory::yes)
160 testContext.getNodePlayer().enableNodeMemorySharing (
true);
164 testContext.setNode(std::move(node));
167 prepareRenderAndDestroy (ut, opts.editName, description, testContext, playHeadState, opts.isMultiThreaded);
172 opts.testSetup, 2, opts.edit->getLength().inSeconds(),
false);
173 prepareRenderAndDestroy (ut, opts.editName, description, testContext, playHeadState, opts.isMultiThreaded);
176 ut.
beginTest (opts.editName +
" - cleanup: " + description);
185 MultiThreaded isMultiThreaded,
189 renderEdit (ut, { &edit, editName, ts, isMultiThreaded, isLockFree, poolType });
209 const auto res = archive.extractAll (tempDir.
getFile(), createdFiles);
213 for (
const auto& f : createdFiles)
215 if (isTracktionEditFile (f))
231 auto id = ProjectItemID::fromProperty (editState, IDs::projectID);
bool deleteRecursively(bool followSymlinks=false) const
bool replaceWithData(const void *dataToWrite, size_t numberOfBytes) const
static String descriptionOfSizeInBytes(int64 bytes)
Result createDirectory() const
const File & getFile() const noexcept
void beginTest(const String &testName)
void expect(bool testResult, const String &failureMessage=String())
static BenchmarkList & getInstance()
Gets the singleton instance.
void addResult(BenchmarkResult r)
Adds a result to the list.
The Tracktion Edit class!
static std::unique_ptr< Edit > createEdit(Options)
Creates an Edit for the given options.
@ forEditing
Creates an Edit for normal use.
static int getDefaultNumUndoLevels() noexcept
Returns the default number of undo levels that should be used.
Determines how the Edit will be created.
The Engine is the central class for all tracktion sessions.
static ProjectItemID createNewID(int projectID) noexcept
Generates a new ID for a given project.
Determines how this block releates to other previous render blocks and if the play head has jumped in...
Converts a monotonically increasing reference range in to a timeline range.
void playSyncedToRange(juce::Range< int64_t > rangeToPlay)
Takes the play position directly from the playout range.
void ignoreUnused(Types &&...) noexcept
juce::ValueTree loadEditFromFile(Engine &e, const juce::File &f, ProjectItemID itemID)
Legacy, will be deprecated soon.
std::unique_ptr< tracktion::graph::Node > createNodeForEdit(EditPlaybackContext &epc, std::atomic< double > &audibleTimeToUpdate, const CreateNodeParams ¶ms)
Creates a Node to play back an Edit with live inputs and outputs.
BenchmarkDescription createBenchmarkDescription(std::string category, std::string name, std::string description)
Creates a description by hashing the name and description fields.
BenchmarkResult createBenchmarkResult(BenchmarkDescription description, const tracktion::graph::PerformanceMeasurement::Statistics &stats)
Creates a BenchmarkResult from a set of Statistics.
Holds the duration a benchmark took to run.
Contains options for Edit Node content creation.
ThreadPoolStrategy
Available strategies for thread pools.
Holds the state of a process call.
Helper class for measuring a benchmark and adding it to the singleton BenchmarkList list.
std::string getDescription() const
Returns a description of the number of channels and length of rendering.
std::unique_ptr< Edit > openEditFromZipData(Engine &engine, const void *data, size_t numBytes)
Loads an Edit that was saved directly from the state to a GZip stream.
std::unique_ptr< Edit > loadEditFromValueTree(Engine &engine, const juce::ValueTree &editState)
Loads an Edit from a value tree with no Project file references.