Google benchmark

From miki
Jump to navigation Jump to search

Links

Example

First make a file hash.cpp containing our function under test

#include <cstdint>

uint64_t hash(uint8_t *str) {
  uint64_t hash = 5381;
  int c;
  while ((c = *str++))
    hash = hash * 33 + c;
  return hash;
}

Create the main module hash_bench.cpp that will call that function using Google benchmark:

#include <cstdint>
#include <cstring>
#include <benchmark/benchmark.h>

extern uint64_t hash(unsigned char *str);

static void BM_hash(benchmark::State& state) {
  char* str = new char[state.range(0)];
  memset(str, 'x', state.range(0));
  for (auto _ : state) {
    benchmark::DoNotOptimize(hash((uint8_t*)str));
  }
  delete[] str;
}

// Register the preceding function as a benchmark and successively pass it
// arguments in [ 8, 16, 32, 64, 128, 256, 512, 1024, 2k, 4k, 8k ]
BENCHMARK(BM_hash)->Range(8, 8<<10);

BENCHMARK_MAIN();

Build with CMake

Use the following CMakeLists.txt project:

cmake_minimum_required(VERSION 3.18.1)
enable_testing()
#include(CheckLibraryExists)

project (chall)
project(HASH)

include(FetchContent)
FetchContent_Declare(
    googletest
    URL https://github.com/google/googletest/archive/075810f7a20405ea09a93f68847d6e963212fa62.zip
    URL_HASH SHA256=19949c33e795197dbb8610672c18bff447dc31faef3257665d69d1bf0884d67b
)

  # For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

FetchContent_Declare(
    googlebenchmark
    URL https://github.com/google/benchmark/archive/refs/tags/v1.6.1.zip
    URL_HASH SHA256=367e963b8620080aff8c831e24751852cffd1f74ea40f25d9cc1b667a9dd5e45
)

FetchContent_MakeAvailable(googlebenchmark)
add_executable(hash hash.cpp hash_bench.cpp)
target_link_libraries(hash benchmark::benchmark)

Then to build:

# To download dependencies and build everything
cmake -E make_directory "build"
# Add -DCMAKE_C_COMPILER=... -DCMAKE_CXX_COMPILER=... here to change compiler
cmake -E chdir "build" cmake -DBENCHMARK_DOWNLOAD_DEPENDENCIES=on -DCMAKE_BUILD_TYPE=Release ../
cmake --build "build" --config Release
build/hash

Build with Make

First get Google benchmark and build it (we follow instructions on GitHub):

git clone https://github.com/google/benchmark.git
cd benchmark
cmake -E make_directory "build"
cmake -E chdir "build" cmake -DBENCHMARK_DOWNLOAD_DEPENDENCIES=on -DCMAKE_BUILD_TYPE=Release ../
cmake --build "build" --config Release
cd ..

Then use the following Makefile:

all: hash

clean:
	rm -f hash

CXX := clang++
CXXFLAGS :=
CXXFLAGS += -O2 -std=c++11
CXXFLAGS += -isystem benchmark/include
CXXFLAGS += -isystem benchmark/build/include
LDFLAGS :=
LDFLAGS += -Lbenchmark/build/src
LIBS :=
LIBS += benchmark pthread

hash: hash.cpp hash_bench.cpp Makefile
	$(CXX) hash.cpp hash_bench.cpp $(CXXFLAGS) $(LDFLAGS) $(LIBS:%=-l%) -o hash

Output

clang++ hash.cpp hash_bench.cpp -O2 -std=c++11 -isystem benchmark/include -isystem benchmark/build/include -Lbenchmark/build/src -lbenchmark -lpthread -o hash
./hash
2022-06-21T18:11:09+02:00
Running ./hash
Run on (8 X 4400 MHz CPU s)
CPU Caches:
  L1 Data 48 KiB (x4)
  L1 Instruction 32 KiB (x4)
  L2 Unified 1280 KiB (x4)
  L3 Unified 8192 KiB (x1)
Load Average: 0.88, 0.82, 1.18
***WARNING*** CPU scaling is enabled, the benchmark real time measurements may be noisy and will incur extra overhead.
-------------------------------------------------------
Benchmark             Time             CPU   Iterations
-------------------------------------------------------
BM_hash/8          4.58 ns         4.58 ns    154392862
BM_hash/64         58.0 ns         58.0 ns     12773604
BM_hash/512         476 ns          476 ns      1368092
BM_hash/4096       3763 ns         3763 ns       185071
BM_hash/8192       7645 ns         7644 ns        88109