perf_tests: Compute metrics for command validation and recording
This CL reads trace events from the tests and computes the total time of validation and command recording. Bug: dawn:208 Change-Id: I551d1e30e60b7d1a839b4fb834ad3608c6cedf63 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/12782 Reviewed-by: Kai Ninomiya <kainino@chromium.org> Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
84bcf44fae
commit
672707f76e
|
@ -21,15 +21,14 @@
|
||||||
|
|
||||||
#include <json/value.h>
|
#include <json/value.h>
|
||||||
#include <json/writer.h>
|
#include <json/writer.h>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
DawnPerfTestEnvironment* gTestEnv = nullptr;
|
DawnPerfTestEnvironment* gTestEnv = nullptr;
|
||||||
|
|
||||||
constexpr double kMicroSecondsPerSecond = 1e6;
|
|
||||||
constexpr double kNanoSecondsPerSecond = 1e9;
|
|
||||||
|
|
||||||
void DumpTraceEventsToJSONFile(
|
void DumpTraceEventsToJSONFile(
|
||||||
const std::vector<DawnPerfTestPlatform::TraceEvent>& traceEventBuffer,
|
const std::vector<DawnPerfTestPlatform::TraceEvent>& traceEventBuffer,
|
||||||
const char* traceFile) {
|
const char* traceFile) {
|
||||||
|
@ -274,40 +273,67 @@ void DawnPerfTestBase::DoRunLoop(double maxRunTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DawnPerfTestBase::OutputResults() {
|
void DawnPerfTestBase::OutputResults() {
|
||||||
double elapsedTimeSeconds[2] = {
|
|
||||||
mTimer->GetElapsedTime(),
|
|
||||||
mGPUTimeNs * 1e-9,
|
|
||||||
};
|
|
||||||
|
|
||||||
const char* clockNames[2] = {
|
|
||||||
"wall_time",
|
|
||||||
"gpu_time",
|
|
||||||
};
|
|
||||||
|
|
||||||
// If measured gpu time is non-zero, print that too.
|
|
||||||
unsigned int clocksToOutput = mGPUTimeNs > 0 ? 2 : 1;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < clocksToOutput; ++i) {
|
|
||||||
double secondsPerStep = elapsedTimeSeconds[i] / static_cast<double>(mNumStepsPerformed);
|
|
||||||
double secondsPerIteration = secondsPerStep / static_cast<double>(mIterationsPerStep);
|
|
||||||
|
|
||||||
// Give the result a different name to ensure separate graphs if we transition.
|
|
||||||
if (secondsPerIteration > 1e-3) {
|
|
||||||
double microSecondsPerIteration = secondsPerIteration * kMicroSecondsPerSecond;
|
|
||||||
PrintResult(clockNames[i], microSecondsPerIteration, "us", true);
|
|
||||||
} else {
|
|
||||||
double nanoSecPerIteration = secondsPerIteration * kNanoSecondsPerSecond;
|
|
||||||
PrintResult(clockNames[i], nanoSecPerIteration, "ns", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DawnPerfTestPlatform* platform =
|
DawnPerfTestPlatform* platform =
|
||||||
reinterpret_cast<DawnPerfTestPlatform*>(gTestEnv->GetInstance()->GetPlatform());
|
reinterpret_cast<DawnPerfTestPlatform*>(gTestEnv->GetInstance()->GetPlatform());
|
||||||
|
|
||||||
std::vector<DawnPerfTestPlatform::TraceEvent> traceEventBuffer =
|
std::vector<DawnPerfTestPlatform::TraceEvent> traceEventBuffer =
|
||||||
platform->AcquireTraceEventBuffer();
|
platform->AcquireTraceEventBuffer();
|
||||||
|
|
||||||
// TODO(enga): Process traces to extract time of command recording, validation, etc.
|
struct EventTracker {
|
||||||
|
double start = std::numeric_limits<double>::max();
|
||||||
|
double end = 0;
|
||||||
|
uint32_t count = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
EventTracker validationTracker = {};
|
||||||
|
EventTracker recordingTracker = {};
|
||||||
|
|
||||||
|
double totalValidationTime = 0;
|
||||||
|
double totalRecordingTime = 0;
|
||||||
|
|
||||||
|
// Note: We assume END timestamps always come after their corresponding BEGIN timestamps.
|
||||||
|
// TODO(enga): When Dawn has multiple threads, stratify by thread id.
|
||||||
|
for (const DawnPerfTestPlatform::TraceEvent& traceEvent : traceEventBuffer) {
|
||||||
|
EventTracker* tracker = nullptr;
|
||||||
|
double* totalTime = nullptr;
|
||||||
|
|
||||||
|
switch (traceEvent.category) {
|
||||||
|
case dawn_platform::TraceCategory::Validation:
|
||||||
|
tracker = &validationTracker;
|
||||||
|
totalTime = &totalValidationTime;
|
||||||
|
break;
|
||||||
|
case dawn_platform::TraceCategory::Recording:
|
||||||
|
tracker = &recordingTracker;
|
||||||
|
totalTime = &totalRecordingTime;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tracker == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (traceEvent.phase == TRACE_EVENT_PHASE_BEGIN) {
|
||||||
|
tracker->start = std::min(tracker->start, traceEvent.timestamp);
|
||||||
|
tracker->count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (traceEvent.phase == TRACE_EVENT_PHASE_END) {
|
||||||
|
tracker->end = std::max(tracker->end, traceEvent.timestamp);
|
||||||
|
ASSERT(tracker->count > 0);
|
||||||
|
tracker->count--;
|
||||||
|
|
||||||
|
if (tracker->count == 0) {
|
||||||
|
*totalTime += (tracker->end - tracker->start);
|
||||||
|
*tracker = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintPerIterationResultFromMilliseconds("wall_time", mTimer->GetElapsedTime() * 1e3, true);
|
||||||
|
PrintPerIterationResultFromMilliseconds("validation_time", totalValidationTime, true);
|
||||||
|
PrintPerIterationResultFromMilliseconds("recording_time", totalRecordingTime, true);
|
||||||
|
|
||||||
const char* traceFile = gTestEnv->GetTraceFile();
|
const char* traceFile = gTestEnv->GetTraceFile();
|
||||||
if (traceFile != nullptr) {
|
if (traceFile != nullptr) {
|
||||||
|
@ -315,6 +341,26 @@ void DawnPerfTestBase::OutputResults() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DawnPerfTestBase::PrintPerIterationResultFromMilliseconds(const std::string& trace,
|
||||||
|
double valueInMilliseconds,
|
||||||
|
bool important) const {
|
||||||
|
if (valueInMilliseconds == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double millisecondsPerIteration =
|
||||||
|
valueInMilliseconds / static_cast<double>(mNumStepsPerformed * mIterationsPerStep);
|
||||||
|
|
||||||
|
// Give the result a different name to ensure separate graphs if we transition.
|
||||||
|
if (millisecondsPerIteration > 1e3) {
|
||||||
|
PrintResult(trace, millisecondsPerIteration, "ms", important);
|
||||||
|
} else if (millisecondsPerIteration > 1) {
|
||||||
|
PrintResult(trace, millisecondsPerIteration * 1e3, "us", important);
|
||||||
|
} else {
|
||||||
|
PrintResult(trace, millisecondsPerIteration * 1e6, "ns", important);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DawnPerfTestBase::PrintResult(const std::string& trace,
|
void DawnPerfTestBase::PrintResult(const std::string& trace,
|
||||||
double value,
|
double value,
|
||||||
const std::string& units,
|
const std::string& units,
|
||||||
|
|
|
@ -73,6 +73,9 @@ class DawnPerfTestBase {
|
||||||
void AbortTest();
|
void AbortTest();
|
||||||
|
|
||||||
void RunTest();
|
void RunTest();
|
||||||
|
void PrintPerIterationResultFromMilliseconds(const std::string& trace,
|
||||||
|
double valueInMilliseconds,
|
||||||
|
bool important) const;
|
||||||
void PrintResult(const std::string& trace,
|
void PrintResult(const std::string& trace,
|
||||||
double value,
|
double value,
|
||||||
const std::string& units,
|
const std::string& units,
|
||||||
|
@ -94,7 +97,6 @@ class DawnPerfTestBase {
|
||||||
const unsigned int mMaxStepsInFlight;
|
const unsigned int mMaxStepsInFlight;
|
||||||
unsigned int mStepsToRun = 0;
|
unsigned int mStepsToRun = 0;
|
||||||
unsigned int mNumStepsPerformed = 0;
|
unsigned int mNumStepsPerformed = 0;
|
||||||
uint64_t mGPUTimeNs = 0; // TODO(enga): Measure GPU time with timing queries.
|
|
||||||
std::unique_ptr<utils::Timer> mTimer;
|
std::unique_ptr<utils::Timer> mTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue