2019-04-25 19:48:56 +08:00
|
|
|
# Benchmark
|
2019-12-01 18:40:10 +08:00
|
|
|
|
2020-09-28 17:54:55 +08:00
|
|
|
[![build-and-test](https://github.com/google/benchmark/workflows/build-and-test/badge.svg)](https://github.com/google/benchmark/actions?query=workflow%3Abuild-and-test)
|
2021-04-20 00:25:59 +08:00
|
|
|
[![bazel](https://github.com/google/benchmark/actions/workflows/bazel.yml/badge.svg)](https://github.com/google/benchmark/actions/workflows/bazel.yml)
|
2020-09-28 17:54:55 +08:00
|
|
|
[![pylint](https://github.com/google/benchmark/workflows/pylint/badge.svg)](https://github.com/google/benchmark/actions?query=workflow%3Apylint)
|
|
|
|
[![test-bindings](https://github.com/google/benchmark/workflows/test-bindings/badge.svg)](https://github.com/google/benchmark/actions?query=workflow%3Atest-bindings)
|
2015-05-13 02:32:44 +08:00
|
|
|
[![Coverage Status](https://coveralls.io/repos/google/benchmark/badge.svg)](https://coveralls.io/r/google/benchmark)
|
2020-09-28 17:54:55 +08:00
|
|
|
|
2023-07-04 15:55:37 +08:00
|
|
|
[![Discord](https://discordapp.com/api/guilds/1125694995928719494/widget.png?style=shield)](https://discord.gg/cz7UX7wKC2)
|
2014-01-08 09:04:19 +08:00
|
|
|
|
2019-04-25 19:48:56 +08:00
|
|
|
A library to benchmark code snippets, similar to unit tests. Example:
|
|
|
|
|
|
|
|
```c++
|
|
|
|
#include <benchmark/benchmark.h>
|
|
|
|
|
|
|
|
static void BM_SomeFunction(benchmark::State& state) {
|
|
|
|
// Perform setup here
|
|
|
|
for (auto _ : state) {
|
|
|
|
// This code gets timed
|
|
|
|
SomeFunction();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Register the function as a benchmark
|
|
|
|
BENCHMARK(BM_SomeFunction);
|
|
|
|
// Run the benchmark
|
|
|
|
BENCHMARK_MAIN();
|
|
|
|
```
|
|
|
|
|
2021-08-18 04:45:33 +08:00
|
|
|
## Getting Started
|
|
|
|
|
2019-04-25 19:48:56 +08:00
|
|
|
To get started, see [Requirements](#requirements) and
|
|
|
|
[Installation](#installation). See [Usage](#usage) for a full example and the
|
2021-08-18 04:45:33 +08:00
|
|
|
[User Guide](docs/user_guide.md) for a more comprehensive feature overview.
|
2019-04-25 19:48:56 +08:00
|
|
|
|
2023-02-07 23:10:30 +08:00
|
|
|
It may also help to read the [Google Test documentation](https://github.com/google/googletest/blob/main/docs/primer.md)
|
2019-04-25 19:48:56 +08:00
|
|
|
as some of the structural aspects of the APIs are similar.
|
|
|
|
|
2021-08-18 04:45:33 +08:00
|
|
|
## Resources
|
2013-12-21 06:51:56 +08:00
|
|
|
|
2018-07-26 21:29:33 +08:00
|
|
|
[Discussion group](https://groups.google.com/d/forum/benchmark-discuss)
|
2014-01-10 02:48:18 +08:00
|
|
|
|
2021-05-20 20:05:50 +08:00
|
|
|
IRC channels:
|
|
|
|
* [libera](https://libera.chat) #benchmark
|
2016-08-30 17:41:58 +08:00
|
|
|
|
2016-12-03 10:47:27 +08:00
|
|
|
[Additional Tooling Documentation](docs/tools.md)
|
|
|
|
|
Add tests to verify assembler output -- Fix DoNotOptimize. (#530)
* Add tests to verify assembler output -- Fix DoNotOptimize.
For things like `DoNotOptimize`, `ClobberMemory`, and even `KeepRunning()`,
it is important exactly what assembly they generate. However, we currently
have no way to test this. Instead it must be manually validated every
time a change occurs -- including a change in compiler version.
This patch attempts to introduce a way to test the assembled output automatically.
It's mirrors how LLVM verifies compiler output, and it uses LLVM FileCheck to run
the tests in a similar way.
The tests function by generating the assembly for a test in CMake, and then
using FileCheck to verify the // CHECK lines in the source file are found
in the generated assembly.
Currently, the tests only run on 64-bit x86 systems under GCC and Clang,
and when FileCheck is found on the system.
Additionally, this patch tries to improve the code gen from DoNotOptimize.
This should probably be a separate change, but I needed something to test.
* Disable assembly tests on Bazel for now
* Link FIXME to github issue
* Fix Tests on OS X
* fix strip_asm.py to work on both Linux and OS X like targets
2018-03-24 06:10:47 +08:00
|
|
|
[Assembly Testing Documentation](docs/AssemblyTests.md)
|
|
|
|
|
2022-05-10 20:16:00 +08:00
|
|
|
[Building and installing Python bindings](docs/python_bindings.md)
|
|
|
|
|
2019-04-25 19:48:56 +08:00
|
|
|
## Requirements
|
|
|
|
|
|
|
|
The library can be used with C++03. However, it requires C++11 to build,
|
|
|
|
including compiler and standard library support.
|
2017-11-30 01:36:19 +08:00
|
|
|
|
2024-06-07 22:22:45 +08:00
|
|
|
_See [dependencies.md](docs/dependencies.md) for more details regarding supported
|
|
|
|
compilers and standards._
|
2017-12-14 07:26:47 +08:00
|
|
|
|
2024-06-07 22:22:45 +08:00
|
|
|
If you have need for a particular compiler to be supported, patches are very welcome.
|
2019-04-25 19:48:56 +08:00
|
|
|
|
2021-08-18 04:45:33 +08:00
|
|
|
See [Platform-Specific Build Instructions](docs/platform_specific_build_instructions.md).
|
2019-09-16 16:05:05 +08:00
|
|
|
|
2019-04-25 19:48:56 +08:00
|
|
|
## Installation
|
|
|
|
|
|
|
|
This describes the installation process using cmake. As pre-requisites, you'll
|
|
|
|
need git and cmake installed.
|
2017-12-14 07:26:47 +08:00
|
|
|
|
2021-08-18 04:45:33 +08:00
|
|
|
_See [dependencies.md](docs/dependencies.md) for more details regarding supported
|
2019-05-01 16:06:12 +08:00
|
|
|
versions of build tools._
|
|
|
|
|
2017-12-14 07:26:47 +08:00
|
|
|
```bash
|
2019-04-25 19:48:56 +08:00
|
|
|
# Check out the library.
|
2017-12-14 07:26:47 +08:00
|
|
|
$ git clone https://github.com/google/benchmark.git
|
2019-08-06 18:36:36 +08:00
|
|
|
# Go to the library root directory
|
|
|
|
$ cd benchmark
|
2019-04-25 19:48:56 +08:00
|
|
|
# Make a build directory to place the build output.
|
2020-08-19 18:57:19 +08:00
|
|
|
$ cmake -E make_directory "build"
|
2021-08-18 04:45:33 +08:00
|
|
|
# Generate build system files with cmake, and download any dependencies.
|
|
|
|
$ cmake -E chdir "build" cmake -DBENCHMARK_DOWNLOAD_DEPENDENCIES=on -DCMAKE_BUILD_TYPE=Release ../
|
2020-08-19 18:57:19 +08:00
|
|
|
# or, starting with CMake 3.13, use a simpler form:
|
|
|
|
# cmake -DCMAKE_BUILD_TYPE=Release -S . -B "build"
|
2019-04-25 19:48:56 +08:00
|
|
|
# Build the library.
|
2020-08-21 23:25:56 +08:00
|
|
|
$ cmake --build "build" --config Release
|
2017-12-14 07:26:47 +08:00
|
|
|
```
|
2019-04-25 19:48:56 +08:00
|
|
|
This builds the `benchmark` and `benchmark_main` libraries and tests.
|
|
|
|
On a unix system, the build directory should now look something like this:
|
|
|
|
|
|
|
|
```
|
|
|
|
/benchmark
|
2019-08-06 18:36:36 +08:00
|
|
|
/build
|
|
|
|
/src
|
|
|
|
/libbenchmark.a
|
|
|
|
/libbenchmark_main.a
|
|
|
|
/test
|
|
|
|
...
|
2019-04-25 19:48:56 +08:00
|
|
|
```
|
|
|
|
|
|
|
|
Next, you can run the tests to check the build.
|
|
|
|
|
|
|
|
```bash
|
2020-08-21 23:25:56 +08:00
|
|
|
$ cmake -E chdir "build" ctest --build-config Release
|
2019-04-25 19:48:56 +08:00
|
|
|
```
|
|
|
|
|
|
|
|
If you want to install the library globally, also run:
|
|
|
|
|
|
|
|
```
|
2020-08-19 18:57:19 +08:00
|
|
|
sudo cmake --build "build" --config Release --target install
|
2019-04-25 19:48:56 +08:00
|
|
|
```
|
2017-12-14 07:26:47 +08:00
|
|
|
|
2018-05-24 17:50:35 +08:00
|
|
|
Note that Google Benchmark requires Google Test to build and run the tests. This
|
|
|
|
dependency can be provided two ways:
|
2017-12-14 07:26:47 +08:00
|
|
|
|
2021-08-18 04:45:33 +08:00
|
|
|
* Checkout the Google Test sources into `benchmark/googletest`.
|
2017-12-14 07:26:47 +08:00
|
|
|
* Otherwise, if `-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON` is specified during
|
2021-08-18 04:45:33 +08:00
|
|
|
configuration as above, the library will automatically download and build
|
|
|
|
any required dependencies.
|
2017-12-14 07:26:47 +08:00
|
|
|
|
2018-01-05 08:13:34 +08:00
|
|
|
If you do not wish to build and run the tests, add `-DBENCHMARK_ENABLE_GTEST_TESTS=OFF`
|
|
|
|
to `CMAKE_ARGS`.
|
|
|
|
|
2019-04-25 19:48:56 +08:00
|
|
|
### Debug vs Release
|
2017-12-14 07:26:47 +08:00
|
|
|
|
2019-04-25 19:48:56 +08:00
|
|
|
By default, benchmark builds as a debug library. You will see a warning in the
|
2020-08-19 18:57:19 +08:00
|
|
|
output when this is the case. To build it as a release library instead, add
|
|
|
|
`-DCMAKE_BUILD_TYPE=Release` when generating the build system files, as shown
|
|
|
|
above. The use of `--config Release` in build commands is needed to properly
|
|
|
|
support multi-configuration tools (like Visual Studio for example) and can be
|
|
|
|
skipped for other build systems (like Makefile).
|
|
|
|
|
|
|
|
To enable link-time optimisation, also add `-DBENCHMARK_ENABLE_LTO=true` when
|
|
|
|
generating the build system files.
|
2017-11-30 01:36:19 +08:00
|
|
|
|
2019-04-25 19:48:56 +08:00
|
|
|
If you are using gcc, you might need to set `GCC_AR` and `GCC_RANLIB` cmake
|
|
|
|
cache variables, if autodetection fails.
|
2017-11-30 01:36:19 +08:00
|
|
|
|
2019-04-25 19:48:56 +08:00
|
|
|
If you are using clang, you may need to set `LLVMAR_EXECUTABLE`,
|
|
|
|
`LLVMNM_EXECUTABLE` and `LLVMRANLIB_EXECUTABLE` cmake cache variables.
|
2017-11-30 01:36:19 +08:00
|
|
|
|
2023-01-17 22:18:57 +08:00
|
|
|
To enable sanitizer checks (eg., `asan` and `tsan`), add:
|
|
|
|
```
|
|
|
|
-DCMAKE_C_FLAGS="-g -O2 -fno-omit-frame-pointer -fsanitize=address -fsanitize=thread -fno-sanitize-recover=all"
|
|
|
|
-DCMAKE_CXX_FLAGS="-g -O2 -fno-omit-frame-pointer -fsanitize=address -fsanitize=thread -fno-sanitize-recover=all "
|
|
|
|
```
|
|
|
|
|
2019-04-25 19:48:56 +08:00
|
|
|
### Stable and Experimental Library Versions
|
2017-12-14 05:51:56 +08:00
|
|
|
|
|
|
|
The main branch contains the latest stable version of the benchmarking library;
|
|
|
|
the API of which can be considered largely stable, with source breaking changes
|
|
|
|
being made only upon the release of a new major version.
|
|
|
|
|
|
|
|
Newer, experimental, features are implemented and tested on the
|
|
|
|
[`v2` branch](https://github.com/google/benchmark/tree/v2). Users who wish
|
|
|
|
to use, test, and provide feedback on the new features are encouraged to try
|
|
|
|
this branch. However, this branch provides no stability guarantees and reserves
|
|
|
|
the right to change and break the API at any time.
|
|
|
|
|
2019-04-25 19:48:56 +08:00
|
|
|
## Usage
|
2019-12-01 18:40:10 +08:00
|
|
|
|
2016-04-20 00:34:13 +08:00
|
|
|
### Basic usage
|
2019-12-01 18:40:10 +08:00
|
|
|
|
2019-04-25 19:48:56 +08:00
|
|
|
Define a function that executes the code to measure, register it as a benchmark
|
|
|
|
function using the `BENCHMARK` macro, and ensure an appropriate `main` function
|
|
|
|
is available:
|
2013-12-21 06:53:25 +08:00
|
|
|
|
2014-02-10 03:45:17 +08:00
|
|
|
```c++
|
2017-09-14 15:31:35 +08:00
|
|
|
#include <benchmark/benchmark.h>
|
|
|
|
|
2014-02-10 03:45:17 +08:00
|
|
|
static void BM_StringCreation(benchmark::State& state) {
|
2017-10-18 02:17:02 +08:00
|
|
|
for (auto _ : state)
|
2014-02-10 03:45:17 +08:00
|
|
|
std::string empty_string;
|
|
|
|
}
|
|
|
|
// Register the function as a benchmark
|
|
|
|
BENCHMARK(BM_StringCreation);
|
|
|
|
|
|
|
|
// Define another benchmark
|
|
|
|
static void BM_StringCopy(benchmark::State& state) {
|
|
|
|
std::string x = "hello";
|
2017-10-18 02:17:02 +08:00
|
|
|
for (auto _ : state)
|
2014-02-10 03:45:17 +08:00
|
|
|
std::string copy(x);
|
|
|
|
}
|
|
|
|
BENCHMARK(BM_StringCopy);
|
|
|
|
|
2015-03-13 12:56:45 +08:00
|
|
|
BENCHMARK_MAIN();
|
2014-02-10 03:45:17 +08:00
|
|
|
```
|
2013-12-21 06:51:56 +08:00
|
|
|
|
2019-04-25 19:48:56 +08:00
|
|
|
To run the benchmark, compile and link against the `benchmark` library
|
2021-06-01 23:05:50 +08:00
|
|
|
(libbenchmark.a/.so). If you followed the build steps above, this library will
|
2020-01-15 04:21:24 +08:00
|
|
|
be under the build directory you created.
|
2019-04-25 19:48:56 +08:00
|
|
|
|
|
|
|
```bash
|
|
|
|
# Example on linux after running the build steps above. Assumes the
|
|
|
|
# `benchmark` and `build` directories are under the current directory.
|
2019-09-27 19:09:23 +08:00
|
|
|
$ g++ mybenchmark.cc -std=c++11 -isystem benchmark/include \
|
|
|
|
-Lbenchmark/build/src -lbenchmark -lpthread -o mybenchmark
|
2019-04-25 19:48:56 +08:00
|
|
|
```
|
|
|
|
|
|
|
|
Alternatively, link against the `benchmark_main` library and remove
|
|
|
|
`BENCHMARK_MAIN();` above to get the same behavior.
|
2017-09-14 15:31:35 +08:00
|
|
|
|
2019-04-25 19:48:56 +08:00
|
|
|
The compiled executable will run all benchmarks by default. Pass the `--help`
|
2021-08-18 04:45:33 +08:00
|
|
|
flag for option information or see the [User Guide](docs/user_guide.md).
|
2019-04-25 19:48:56 +08:00
|
|
|
|
2020-01-15 04:21:24 +08:00
|
|
|
### Usage with CMake
|
|
|
|
|
|
|
|
If using CMake, it is recommended to link against the project-provided
|
|
|
|
`benchmark::benchmark` and `benchmark::benchmark_main` targets using
|
|
|
|
`target_link_libraries`.
|
|
|
|
It is possible to use ```find_package``` to import an installed version of the
|
|
|
|
library.
|
|
|
|
```cmake
|
|
|
|
find_package(benchmark REQUIRED)
|
|
|
|
```
|
|
|
|
Alternatively, ```add_subdirectory``` will incorporate the library directly in
|
|
|
|
to one's CMake project.
|
|
|
|
```cmake
|
|
|
|
add_subdirectory(benchmark)
|
|
|
|
```
|
|
|
|
Either way, link to the library as follows.
|
|
|
|
```cmake
|
|
|
|
target_link_libraries(MyTarget benchmark::benchmark)
|
|
|
|
```
|