Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/benchmarks/AP_gbenchmark.h
Views: 1798
/*1* Utility header for benchmarks with Google Benchmark.2*/3#include <benchmark/benchmark.h>45/* The two functions below are an approach proposed by Chandler Carruth in6* CPPCON 2015: CppCon 2015: "Tuning C++: Benchmarks, and CPUs, and Compilers!7* Oh My!" in order keep the compiler from optimizing the use of a variable8* (gbenchmark_escape) or whole memory (gbenchmark_clobber).9*10* The compiler optimizer may sometimes remove code when it sees it isn't11* necessary. For example, when a variable isn't used, the optimizer removes12* the code that computes the value for that variable - that's not good for13* benchmarks. The function gbenchmark_escape(void *p) makes the compiler think14* that that p is being used in a code that might have "unknowable side15* effects", which keeps it from removing the variable. The "side effects" in16* the case here would be the benchmark numbers.17*18* Here is an example that would give wrong benchmark values:19*20* static void BM_Test(benchmark::State& state)21* {22* while (state.KeepRunning()) {23* float a = expensive_operation();24* }25* }26*27* Since variable a isn't used, the call to expensive_operation() is removed28* from the compiled program. The benchmark would show that29* expensive_operation() is extremely fast. The following code would fix that:30*31* static void BM_Test(benchmark::State& state)32* {33* while (state.KeepRunning()) {34* float a = expensive_operation();35* gbenchmark_escape(&a);36* }37* }38*/3940inline void gbenchmark_escape(void* p)41{42asm volatile("" : : "g"(p) : "memory");43}4445inline void gbenchmark_clobber()46{47asm volatile("" : : : "memory");48}495051