diff options
Diffstat (limited to '')
-rw-r--r-- | gfx/skia/skia/src/utils/SkBlitterTraceCommon.h | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/gfx/skia/skia/src/utils/SkBlitterTraceCommon.h b/gfx/skia/skia/src/utils/SkBlitterTraceCommon.h new file mode 100644 index 0000000000..b4adb5ce77 --- /dev/null +++ b/gfx/skia/skia/src/utils/SkBlitterTraceCommon.h @@ -0,0 +1,180 @@ +/* + * Copyright 2022 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * This is an experimental (and probably temporary) solution that allows + * to compare performance SkVM blitters vs RasterPipeline blitters. + * In addition to measuring performance (which is questionable) it also produces + * other counts (pixels, scanlines) and more detailed traces that + * can explain the current results (SkVM is slower) and help improve it. + * The entire code is hidden under build flag skia_compare_vm_vs_rp=true + * and will not appear at all without it. + */ + +#ifndef SkBlitterTraceCommon_DEFINED +#define SkBlitterTraceCommon_DEFINED + +#include <inttypes.h> +#include <unordered_map> + +#define SK_BLITTER_TRACE_NO_CODE do {} while (0) + +#ifdef SKIA_COMPARE_VM_VS_RP + +#include "src/utils/SkCycles.h" + +class SkBlitterTrace { +/* + * This class collects information for RasterPipeLine vs SkVM + * performance comparison. + * How to get the comparison table: + * 1. Add to your Release/args.gn an argument: skia_compare_vm_vs_rp=true + * Build nanobench. + * 2. Run nanobench for SkVM: + * []/Release/nanobench + * --csv --config 8888 --skvm --loops 100 --samples 1 + * --match $(ls skps | grep --invert-match svg ) 2>&1 | tee VM.data + * 3. Run nanobench for RasterPipeLine: + * []/Release/nanobench + * --csv --config 8888 --forceRasterPipeline --loops 100 + * --samples 1 --match $(ls skps | grep --invert-match svg ) + * 2>&1 | tee RP.data + * 4. Extract the information side-by-side: + * awk 'BEGIN {OFS=","; fileNum = 0} ($2 ~ /MB/) && fileNum == 0 + * {vmvmcycles[$3] = $6; vmvmscan[$3] = $8; vmvmpixels[$3] = $10; + * vmvminterp[$3] = $11; vmrpcycle[$3] = $14; vmrpscan[$3] = $16; + * vmrppixels[$3] = $18} ($2 ~ /MB/) && fileNum == 1 {print $3, + * vmvmcycles[$3], vmvmscan[$3], vmvmpixels[$3], vmvminterp[$3], $6, $8, + * $10, $11, $14, $16, $18} ENDFILE {fileNum += 1}' + * VM.data RP.data > compare.csv + * 5. Open the compare.csv table in Google Spreadsheets. + * You will get columns [A:P]. Add 4 more columns with formulas: + * Q: =B/M-1 + * R: =N-C + * S: =O-D + * T: =2*(S<>0)+(R<>0) + * To be honest R, S, T columns are here for checking only (they all + * supposed to have zero values in them) + * Column Q shows the actual performance difference. Negative value means + * that wins SkVM, positive - RasterPipeLine. + */ +public: + SkBlitterTrace(const char* header, bool traceSteps = false) + : fHeader(header), fTraceSteps(traceSteps) { } + + SkBlitterTrace& operator= (const SkBlitterTrace&) = default; + + void addTrace(const char* name, uint64_t cycles, uint64_t scanLines, uint64_t pixels) { + fCycles += cycles; + fScanlines += scanLines; + fPixels += pixels; + if (fTraceSteps) { + printIncrements(name, cycles, scanLines, pixels); + } + } + + void reset() { + fCycles = 0ul; + fScanlines = 0ul; + fPixels = 0ul; + } + + void printIncrements(const char* name, + uint64_t cycles, + uint64_t scanLines, + uint64_t pixels) const { + SkDebugf("%s %s: cycles=%" PRIu64 "+%" PRIu64 + " scanlines=%" PRIu64 "+%" PRIu64 " pixels=%" PRIu64, + fHeader, name, + fCycles - cycles, cycles, + fScanlines - scanLines, scanLines, + fPixels); + SkDebugf("\n"); + } + + void printCounts(const char* name) const { + SkDebugf("%s cycles: %" PRIu64 " " + " scanlines: %" PRIu64 " pixels: %" PRIu64, + fHeader, + fCycles, + fScanlines, + fPixels); + SkDebugf(" "); + } + + uint64_t getCycles() const { return fCycles; } + uint64_t getScanlines() const { return fScanlines; } + uint64_t getPixels() const { return fPixels; } + + class Step { + public: + Step(SkBlitterTrace* trace, + const char* name, + uint64_t scanlines, + uint64_t pixels) + : fTrace(trace) + , fName(name) + , fScanlines(scanlines) + , fPixels(pixels) { + fStartTime = SkCycles::Now(); + } + void add(uint64_t scanlines, uint64_t pixels) { + fScanlines += scanlines; + fPixels += pixels; + } + ~Step() { + if (fTrace == nullptr) { + return; + } + auto endTime = SkCycles::Now() - fStartTime; + fTrace->addTrace(/*name=*/fName, + /*cycles=*/endTime, + /*scanlines=*/fScanlines, + /*pixels=*/fPixels); + } + private: + SkBlitterTrace* fTrace = nullptr; + const char* fName = ""; + uint64_t fStartTime = 0ul; + uint64_t fScanlines = 0ul; + uint64_t fPixels = 0ul; + }; + +private: + const char* fHeader = ""; + bool fTraceSteps = false; + uint64_t fCycles = 0ul; + uint64_t fScanlines = 0ul; + uint64_t fPixels = 0ul; +}; + +#define SK_BLITTER_TRACE_INIT \ +extern SkBlitterTrace gSkVMBlitterTrace; \ +extern SkBlitterTrace gSkRPBlitterTrace; \ + \ +static SkBlitterTrace gSkVMBlitterTraceCapture("VM", false); \ +static SkBlitterTrace gSkRPBlitterTraceCapture("RP", false); + +#define SK_BLITTER_TRACE_LOCAL_SETUP \ + gSkVMBlitterTrace.reset(); \ + gSkRPBlitterTrace.reset() + +#define SK_BLITTER_TRACE_LOCAL_TEARDOWN \ + gSkVMBlitterTraceCapture = gSkVMBlitterTrace; \ + gSkRPBlitterTraceCapture = gSkRPBlitterTrace + +#define SK_BLITTER_TRACE_PRINT \ + gSkVMBlitterTraceCapture.printCounts("Total"); \ + SkDebugf("0 "); \ + gSkRPBlitterTraceCapture.printCounts("Total") + +#else +#define SK_BLITTER_TRACE_INIT +#define SK_BLITTER_TRACE_LOCAL_SETUP SK_BLITTER_TRACE_NO_CODE +#define SK_BLITTER_TRACE_LOCAL_TEARDOWN SK_BLITTER_TRACE_NO_CODE +#define SK_BLITTER_TRACE_PRINT SK_BLITTER_TRACE_NO_CODE +#endif // SKIA_COMPARE_VM_VS_RP + +#endif // SkBlitterTraceCommon_DEFINED |