Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1592)

Unified Diff: tools/kilobench/kilobench.cpp

Issue 1594553003: Modify kilobench to run each sample in its own process (Closed) Base URL: https://skia.googlesource.com/skia.git@kilobench-2-setupcanvas
Patch Set: check return values of pipe, read, write Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gyp/most.gyp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/kilobench/kilobench.cpp
diff --git a/tools/kilobench/kilobench.cpp b/tools/kilobench/kilobench.cpp
index 438e582324fb2e8c97f1da061e7d9a3f8760d870..8c844f47e0169ac26f72cae33d22b03fb52d8e50 100644
--- a/tools/kilobench/kilobench.cpp
+++ b/tools/kilobench/kilobench.cpp
@@ -8,6 +8,7 @@
#include "GrCaps.h"
#include "GrContextFactory.h"
#include "Benchmark.h"
+#include "ResultsWriter.h"
#include "SkCommandLineFlags.h"
#include "SkOSFile.h"
#include "SkStream.h"
@@ -18,6 +19,11 @@
#include "VisualSKPBench.h"
#include "gl/GrGLDefines.h"
+// posix only for now
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
/*
* This is an experimental GPU only benchmarking program. The initial implementation will only
* support SKPs.
@@ -63,6 +69,11 @@ DEFINE_int32(loops, kDefaultLoops, loops_help_txt().c_str());
DEFINE_double(gpuMs, 5, "Target bench time in millseconds for GPU.");
DEFINE_string2(writePath, w, "", "If set, write bitmaps here as .pngs.");
+static SkString humanize(double ms) {
+ return HumanizeMs(ms);
+}
+#define HUMANIZE(ms) humanize(ms).c_str()
+
namespace kilobench {
class BenchmarkStream {
public:
@@ -322,76 +333,135 @@ static int setup_gpu_bench(GPUTarget* target, Benchmark* bench, int maxGpuFrameL
return loops;
}
-static SkString humanize(double ms) {
- return HumanizeMs(ms);
-}
-#define HUMANIZE(ms) humanize(ms).c_str()
+struct AutoSetupContextBenchAndTarget {
+ AutoSetupContextBenchAndTarget(Benchmark* bench) : fBenchmark(bench) {
+ GrContextOptions grContextOpts;
+ fCtxFactory.reset(new GrContextFactory(grContextOpts));
-void benchmark_inner_loop(Benchmark* bench, GrContextFactory* ctxFactory) {
- SkTArray<double> samples;
- GPUTarget target;
- SkAssertResult(target.init(bench, ctxFactory, false,
- GrContextFactory::kNative_GLContextType,
- GrContextFactory::kNone_GLContextOptions, 0));
+ SkAssertResult(fTarget.init(bench, fCtxFactory, false,
+ GrContextFactory::kNative_GLContextType,
+ GrContextFactory::kNone_GLContextOptions, 0));
- SkCanvas* canvas = target.getCanvas();
- target.setup();
+ fCanvas = fTarget.getCanvas();
+ fTarget.setup();
- bench->perCanvasPreDraw(canvas);
- int maxFrameLag;
- target.needsFrameTiming(&maxFrameLag);
- int loops = setup_gpu_bench(&target, bench, maxFrameLag);
+ bench->perCanvasPreDraw(fCanvas);
+ fTarget.needsFrameTiming(&fMaxFrameLag);
+ }
+
+ int getLoops() { return setup_gpu_bench(&fTarget, fBenchmark, fMaxFrameLag); }
- samples.reset(FLAGS_samples);
- for (int s = 0; s < FLAGS_samples; s++) {
- samples[s] = time(loops, bench, &target) / loops;
+ double timeSample(int loops) {
+ for (int i = 0; i < fMaxFrameLag; i++) {
+ time(loops, fBenchmark, &fTarget);
+ }
+
+ return time(loops, fBenchmark, &fTarget) / loops;
}
+ void teardownBench() { fBenchmark->perCanvasPostDraw(fCanvas); }
+
+ SkAutoTDelete<GrContextFactory> fCtxFactory;
+ GPUTarget fTarget;
+ SkCanvas* fCanvas;
+ Benchmark* fBenchmark;
+ int fMaxFrameLag;
+};
- bench->perCanvasPostDraw(canvas);
-
- Stats stats(samples);
- const double stddev_percent = 100 * sqrt(stats.var) / stats.mean;
- SkDebugf("%d\t%s\t%s\t%s\t%s\t%.0f%%\t%s\t%s\t%s\n"
- , loops
- , HUMANIZE(stats.min)
- , HUMANIZE(stats.median)
- , HUMANIZE(stats.mean)
- , HUMANIZE(stats.max)
- , stddev_percent
- , stats.plot.c_str()
- , "gpu"
- , bench->getUniqueName()
- );
+int setup_loops(Benchmark* bench) {
+ AutoSetupContextBenchAndTarget ascbt(bench);
+ int loops = ascbt.getLoops();
+ ascbt.teardownBench();
if (!FLAGS_writePath.isEmpty() && FLAGS_writePath[0]) {
SkString pngFilename = SkOSPath::Join(FLAGS_writePath[0], "gpu");
pngFilename = SkOSPath::Join(pngFilename.c_str(), bench->getUniqueName());
pngFilename.append(".png");
- write_canvas_png(&target, pngFilename);
+ write_canvas_png(&ascbt.fTarget, pngFilename);
}
+ return loops;
}
-} // namespace kilobench
+double time_sample(Benchmark* bench, int loops) {
+ AutoSetupContextBenchAndTarget ascbt(bench);
+ double sample = ascbt.timeSample(loops);
+ ascbt.teardownBench();
-int kilobench_main() {
- SkAutoTDelete<GrContextFactory> ctxFactory;
+ return sample;
+}
- GrContextOptions grContextOpts;
- ctxFactory.reset(new GrContextFactory(grContextOpts));
+} // namespace kilobench
+
+static const int kOutResultSize = 1024;
+int kilobench_main() {
kilobench::BenchmarkStream benchStream;
SkDebugf("loops\tmin\tmedian\tmean\tmax\tstddev\t%-*s\tconfig\tbench\n",
FLAGS_samples, "samples");
+ int descriptors[2];
+ if (pipe(descriptors) != 0) {
+ SkFAIL("Failed to open a pipe\n");
+ }
+
while (Benchmark* b = benchStream.next()) {
SkAutoTDelete<Benchmark> bench(b);
- kilobench::benchmark_inner_loop(bench.get(), ctxFactory.get());
- }
- // Make sure we clean up the global GrContextFactory here, otherwise we might race with the
- // SkEventTracer destructor
- ctxFactory.reset(nullptr);
+ int loops;
+ SkTArray<double> samples;
+ for (int i = 0; i < FLAGS_samples + 1; i++) {
+ // We fork off a new process to setup the grcontext and run the test while we wait
+ int childPid = fork();
+ if (childPid > 0) {
+ char result[kOutResultSize];
+ if (read(descriptors[0], result, kOutResultSize) < 0) {
+ SkFAIL("Failed to read from pipe\n");
+ }
+
+ // if samples == 0 then parse # of loops
+ // else parse float
+ if (i == 0) {
+ sscanf(result, "%d", &loops);
+ } else {
+ sscanf(result, "%lf", &samples.push_back());
+ }
+
+ // wait until exit
+ int status;
+ waitpid(childPid, &status, 0);
+ } else if (0 == childPid) {
+ char result[kOutResultSize];
+ if (i == 0) {
+ sprintf(result, "%d", kilobench::setup_loops(bench));
+ } else {
+ sprintf(result, "%lf", kilobench::time_sample(bench, loops));
+ }
+
+ // Make sure to write the null terminator
+ if (write(descriptors[1], result, strlen(result) + 1) < 0) {
+ SkFAIL("Failed to write to pipe\n");
+ }
+ return 0;
+ } else {
+ SkFAIL("Fork failed\n");
+ }
+ }
+
+ Stats stats(samples);
+ const double stddev_percent = 100 * sqrt(stats.var) / stats.mean;
+ SkDebugf("%d\t%s\t%s\t%s\t%s\t%.0f%%\t%s\t%s\t%s\n"
+ , loops
+ , HUMANIZE(stats.min)
+ , HUMANIZE(stats.median)
+ , HUMANIZE(stats.mean)
+ , HUMANIZE(stats.max)
+ , stddev_percent
+ , stats.plot.c_str()
+ , "gpu"
+ , bench->getUniqueName()
+ );
+
+ }
return 0;
}
« no previous file with comments | « gyp/most.gyp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698