Update third_party/benchmark to 1.9.5

Picks up
https://github.com/google/benchmark/commit/d8db2f90b643eb28a12976beb4d57bcfb639911d

This results in deprecation warnings with benchmark::internal::Benchmark
so go ahead and fix those.

Also add third_party/benchmark to .bazelignore. This stops
`bazel test ...` from recursing in here. It looks like we previously
suppressed copying some files, but we can avoid having to post-process
the files this way.

Change-Id: Idf20fce28153a450fe03e121d9bc0d601d43ec6c
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/88948
Auto-Submit: David Benjamin <davidben@google.com>
Reviewed-by: Lily Chen <chlily@google.com>
Commit-Queue: Lily Chen <chlily@google.com>
This commit is contained in:
David Benjamin
2026-02-09 16:47:14 -05:00
committed by Boringssl LUCI CQ
parent e50923e3de
commit 2a5cd33a2a
105 changed files with 2092 additions and 364 deletions
+1
View File
@@ -1,2 +1,3 @@
third_party/benchmark
third_party/googletest
util/bazel-example
+1 -1
View File
@@ -36,7 +36,7 @@ module(
# https://github.com/bazelbuild/bazel/issues/22187 is ever fixed, we can change
# this.
bazel_dep(name = "googletest", version = "1.17.0.bcr.2")
bazel_dep(name = "google_benchmark", version = "1.9.4")
bazel_dep(name = "google_benchmark", version = "1.9.5")
bazel_dep(name = "platforms", version = "1.0.0")
bazel_dep(name = "rules_cc", version = "0.2.14")
bazel_dep(name = "rules_license", version = "1.0.0")
+2 -2
View File
@@ -44,8 +44,8 @@
"https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84",
"https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8",
"https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb",
"https://bcr.bazel.build/modules/google_benchmark/1.9.4/MODULE.bazel": "3bab7c17c10580f87b647478a72a05621f88abc275afb97b578c828f56e59d45",
"https://bcr.bazel.build/modules/google_benchmark/1.9.4/source.json": "8e0036f76a5c2aa9c16ca0da57d8065cff69edeed58f1f85584c588c0ef723a5",
"https://bcr.bazel.build/modules/google_benchmark/1.9.5/MODULE.bazel": "8a85cfd90b1e45e6e68f1aa2aa9efce3c04add57df732571d7fd54c07e7c5143",
"https://bcr.bazel.build/modules/google_benchmark/1.9.5/source.json": "0bd357fd9db30ee31d5eb4c78b1086ce3d79b4423ce76de19e8a2fa7b2fa2e10",
"https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4",
"https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6",
"https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f",
+1 -1
View File
@@ -118,7 +118,7 @@ void BM_SpeedAEAD(benchmark::State &state, size_t ad_len,
static const int64_t kInputSizes[] = {16, 256, 1350, 8192, 16384};
void SetInputLength(benchmark::internal::Benchmark *bench) {
void SetInputLength(benchmark::Benchmark *bench) {
bench->ArgName("InputSize");
auto input_sizes = bench::GetInputSizes(bench);
if (input_sizes.empty()) {
+1 -1
View File
@@ -46,7 +46,7 @@ void BM_SpeedHash(benchmark::State &state, const EVP_MD *md) {
static const int64_t kInputSizes[] = {16, 256, 1350, 8192, 16384};
void SetInputLength(benchmark::internal::Benchmark *bench) {
void SetInputLength(benchmark::Benchmark *bench) {
bench->ArgName("InputSize");
auto input_sizes = bssl::bench::GetInputSizes(bench);
if (input_sizes.empty()) {
+2 -2
View File
@@ -63,7 +63,7 @@ int RegisterBenchmark(void (*handle)());
//
// This function can only be used in the context of |BSSL_BENCH_LAZY_REGISTER|.
// Otherwise, the benchmark will be aborted.
void SetThreads(benchmark::internal::Benchmark *bench);
void SetThreads(benchmark::Benchmark *bench);
// For benchmark registration, get the input size from the runtime flag.
// This is an interim solution, until the next `google/benchmark` release,
@@ -71,7 +71,7 @@ void SetThreads(benchmark::internal::Benchmark *bench);
//
// This function can only be used in the context of |BSSL_BENCH_LAZY_REGISTER|.
// Otherwise, the benchmark will be aborted.
Span<const int64_t> GetInputSizes(benchmark::internal::Benchmark *bench);
Span<const int64_t> GetInputSizes(benchmark::Benchmark *bench);
} // namespace bench
+2 -2
View File
@@ -46,7 +46,7 @@ std::vector<int> &GetNumThreadsList() {
}
} // namespace
void SetThreads(benchmark::internal::Benchmark *bench) {
void SetThreads(benchmark::Benchmark *bench) {
if (!flags_parsed) {
fprintf(stderr,
"Benchmark %s attempts to set thread count before flag parsing is "
@@ -71,7 +71,7 @@ int RegisterBenchmark(void (*handle)()) {
return 0;
}
Span<const int64_t> GetInputSizes(benchmark::internal::Benchmark *bench) {
Span<const int64_t> GetInputSizes(benchmark::Benchmark *bench) {
if (!flags_parsed) {
fprintf(stderr,
"Benchmark %s attempts to set thread count before flag parsing is "
+1 -1
View File
@@ -39,7 +39,7 @@ void BM_SpeedRandom(benchmark::State &state) {
static const int64_t kInputSizes[] = {16, 256, 1350, 8192, 16384};
void SetInputLength(benchmark::internal::Benchmark *bench) {
void SetInputLength(benchmark::Benchmark *bench) {
bench->ArgName("InputSize");
auto input_sizes = bssl::bench::GetInputSizes(bench);
if (input_sizes.empty()) {
+1
View File
@@ -0,0 +1 @@
8.2.1
+11
View File
@@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: daily
- package-ecosystem: pip
directory: /tools
schedule:
interval: daily
+5 -2
View File
@@ -7,6 +7,9 @@ on:
env:
CMAKE_GENERATOR: Ninja
permissions:
contents: read
jobs:
build_and_test_default:
name: bazel.${{ matrix.os }}
@@ -16,10 +19,10 @@ jobs:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: mount bazel cache
uses: actions/cache@v4
uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
env:
cache-name: bazel-cache
with:
@@ -19,9 +19,9 @@ jobs:
os: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: lukka/get-cmake@latest
- uses: lukka/get-cmake@9e07ecdcee1b12e5037e42f410b67f03e2f626e1 # latest
with:
cmakeVersion: 3.13.0
@@ -9,6 +9,9 @@ on:
env:
CMAKE_GENERATOR: Ninja
permissions:
contents: read
jobs:
job:
# TODO(dominic): Extend this to include compiler and set through env: CC/CXX.
@@ -20,7 +23,7 @@ jobs:
os: [ubuntu-latest]
build_type: ['Release', 'Debug']
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: install libpfm
run: |
+10 -10
View File
@@ -30,10 +30,10 @@ jobs:
if: runner.os == 'macOS'
run: brew install ninja
- uses: actions/checkout@v4
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: build
uses: threeal/cmake-action@v2.1.0
uses: threeal/cmake-action@725d1314ccf9ea922805d7e3f9d9bcbca892b406 # v2.1.0
with:
build-dir: ${{ runner.workspace }}/_build
cxx-compiler: ${{ matrix.compiler }}
@@ -60,7 +60,7 @@ jobs:
fail-fast: false
matrix:
msvc:
- VS-16-2019
- VS-17-2025
- VS-17-2022
build_type:
- Debug
@@ -69,17 +69,17 @@ jobs:
- shared
- static
include:
- msvc: VS-16-2019
os: windows-2019
generator: 'Visual Studio 16 2019'
- msvc: VS-17-2025
os: windows-2025
generator: 'Visual Studio 17 2022'
- msvc: VS-17-2022
os: windows-2022
generator: 'Visual Studio 17 2022'
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: lukka/get-cmake@latest
- uses: lukka/get-cmake@9e07ecdcee1b12e5037e42f410b67f03e2f626e1 # latest
- name: configure cmake
run: >
@@ -117,7 +117,7 @@ jobs:
steps:
- name: setup msys2
uses: msys2/setup-msys2@v2
uses: msys2/setup-msys2@4f806de0a5a7294ffabaff804b38a9b435a73bda # v2.30.0
with:
cache: false
msystem: ${{ matrix.msys2.msystem }}
@@ -131,7 +131,7 @@ jobs:
cmake:p
ninja:p
- uses: actions/checkout@v4
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
# NOTE: we can't use cmake actions here as we need to do everything in msys2 shell.
- name: configure cmake
@@ -6,14 +6,17 @@ on:
env:
CMAKE_GENERATOR: Ninja
permissions:
contents: read
jobs:
job:
name: check-clang-format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: DoozyX/clang-format-lint-action@v0.18.2
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: DoozyX/clang-format-lint-action@bcb4eb2cb0d707ee4f3e5cc3b456eb075f12cf73 # v0.20
with:
source: './include/benchmark ./src ./test'
source: './include/benchmark ./src ./test ./bindings'
clangFormatVersion: 18
@@ -7,6 +7,9 @@ on:
env:
CMAKE_GENERATOR: Ninja
permissions:
contents: read
jobs:
job:
name: run-clang-tidy
@@ -14,7 +17,7 @@ jobs:
strategy:
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: install clang-tidy
run: sudo apt update && sudo apt -y install clang-tidy
+4 -1
View File
@@ -9,13 +9,16 @@ on:
env:
CMAKE_GENERATOR: Ninja
permissions:
contents: read
jobs:
build-and-deploy:
name: Build HTML documentation
runs-on: ubuntu-latest
steps:
- name: Fetching sources
uses: actions/checkout@v4
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Installing build dependencies
run: |
+27
View File
@@ -0,0 +1,27 @@
name: OSSF Scorecard Weekly
on:
schedule:
- cron: '0 0 * * 0' # Runs every Sunday at midnight UTC
workflow_dispatch:
permissions:
contents: read
jobs:
ossf-scorecard:
# To write a badge
permissions:
id-token: write
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Run analysis
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
with:
publish_results: true
results_file: ossf_scorecard.json
results_format: json
+6 -25
View File
@@ -6,36 +6,17 @@ on:
pull_request:
branches: [ main ]
env:
CMAKE_GENERATOR: Ninja
jobs:
pre-commit:
runs-on: ubuntu-latest
env:
MYPY_CACHE_DIR: "${{ github.workspace }}/.cache/mypy"
RUFF_CACHE_DIR: "${{ github.workspace }}/.cache/ruff"
PRE_COMMIT_HOME: "${{ github.workspace }}/.cache/pre-commit"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b # v7.2.0
with:
python-version: 3.11
cache: pip
cache-dependency-path: pyproject.toml
- name: Install dependencies
run: python -m pip install ".[dev]"
- name: Cache pre-commit tools
uses: actions/cache@v4
with:
path: |
${{ env.MYPY_CACHE_DIR }}
${{ env.RUFF_CACHE_DIR }}
${{ env.PRE_COMMIT_HOME }}
key: ${{ runner.os }}-${{ hashFiles('.pre-commit-config.yaml') }}-linter-cache
python-version: 3.12
- name: Run pre-commit checks
run: pre-commit run --all-files --verbose --show-diff-on-failure
run: uv run --only-group=dev pre-commit run --all-files --verbose --show-diff-on-failure
+2 -2
View File
@@ -19,7 +19,7 @@ jobs:
sanitizer: ['asan', 'ubsan', 'tsan', 'msan']
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: configure msan env
if: matrix.sanitizer == 'msan'
@@ -52,7 +52,7 @@ jobs:
echo "ASAN_OPTIONS=alloc_dealloc_mismatch=0" >> $GITHUB_ENV
- name: setup clang
uses: egor-tensin/setup-clang@v1
uses: egor-tensin/setup-clang@471a6f8ef1d449dba8e1a51780e7f943572a3f99 # v2.1
with:
version: latest
platform: x64
+5 -2
View File
@@ -9,6 +9,9 @@ on:
env:
CMAKE_GENERATOR: Ninja
permissions:
contents: read
jobs:
python_bindings:
name: Test GBM Python ${{ matrix.python-version }} bindings on ${{ matrix.os }}
@@ -20,11 +23,11 @@ jobs:
python-version: [ "3.10", "3.11", "3.12", "3.13" ]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: ${{ matrix.python-version }}
- name: Install GBM Python bindings on ${{ matrix.os }}
+13 -12
View File
@@ -15,17 +15,17 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out repo
uses: actions/checkout@v4
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Install Python 3.12
uses: actions/setup-python@v5
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: "3.12"
- run: python -m pip install build
- name: Build sdist
run: python -m build --sdist
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: dist-sdist
path: dist/*.tar.gz
@@ -35,21 +35,22 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, ubuntu-24.04-arm, macos-13, macos-14, windows-latest]
os: [ubuntu-latest, ubuntu-24.04-arm, macos-15-intel, macos-latest, windows-latest]
steps:
- name: Check out Google Benchmark
uses: actions/checkout@v4
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- uses: actions/setup-python@v5
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
name: Install Python 3.12
with:
python-version: "3.12"
- run: pip install --upgrade pip uv
- name: Install the latest version of uv
uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b # v7.2.0
- name: Build wheels on ${{ matrix.os }} using cibuildwheel
uses: pypa/cibuildwheel@v2.23.2
uses: pypa/cibuildwheel@298ed2fb2c105540f5ed055e8a6ad78d82dd3a7e # v3.3.1
env:
CIBW_BUILD: "cp310-* cp311-* cp312-*"
CIBW_BUILD_FRONTEND: "build[uv]"
@@ -60,10 +61,10 @@ jobs:
CIBW_ENVIRONMENT_LINUX: PATH=$PATH:$HOME/bin
CIBW_TEST_COMMAND: python {project}/bindings/python/google_benchmark/example.py
# unused by Bazel, but needed explicitly by delocate on MacOS.
MACOSX_DEPLOYMENT_TARGET: "10.14"
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.os == 'macos-15-intel' && 10.14 || 11.0 }}
- name: Upload Google Benchmark ${{ matrix.os }} wheels
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: dist-${{ matrix.os }}
path: wheelhouse/*.whl
@@ -75,9 +76,9 @@ jobs:
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
path: dist
pattern: dist-*
merge-multiple: true
- uses: pypa/gh-action-pypi-publish@release/v1
- uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1
+1
View File
@@ -66,3 +66,4 @@ CMakeSettings.json
# Python build stuff
dist/
*.egg-info*
uv.lock
+4 -4
View File
@@ -1,18 +1,18 @@
repos:
- repo: https://github.com/keith/pre-commit-buildifier
rev: 8.0.3
rev: 8.2.1
hooks:
- id: buildifier
- id: buildifier-lint
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.15.0
rev: v1.18.2
hooks:
- id: mypy
types_or: [ python, pyi ]
args: [ "--ignore-missing-imports", "--scripts-are-modules" ]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.11.8
rev: v0.14.0
hooks:
- id: ruff
- id: ruff-check
args: [ --fix, --exit-non-zero-on-fix ]
- id: ruff-format
+4
View File
@@ -44,6 +44,7 @@ Jordan Williams <jwillikers@protonmail.com>
Jussi Knuuttila <jussi.knuuttila@gmail.com>
Kaito Udagawa <umireon@gmail.com>
Kishan Kumar <kumar.kishan@outlook.com>
Kostiantyn Lazukin <konstantin.lazukin@gmail.com>
Lei Xu <eddyxu@gmail.com>
Marcel Jacobse <mjacobse@uni-bremen.de>
Matt Clarkson <mattyclarkson@gmail.com>
@@ -54,14 +55,17 @@ MongoDB Inc.
Nick Hutchinson <nshutchinson@gmail.com>
Norman Heino <norman.heino@gmail.com>
Oleksandr Sochka <sasha.sochka@gmail.com>
Olga Fadeeva <olga.kiselik@gmail.com>
Ori Livneh <ori.livneh@gmail.com>
Paul Redmond <paul.redmond@gmail.com>
Prithvi Rao <ee22b024@smail.iitm.ac.in>
Radoslav Yovchev <radoslav.tm@gmail.com>
Raghu Raja <raghu@enfabrica.net>
Rainer Orth <ro@cebitec.uni-bielefeld.de>
Roman Lebedev <lebedev.ri@gmail.com>
Sayan Bhattacharjee <aero.sayan@gmail.com>
Shapr3D <google-contributors@shapr3d.com>
Shashank Thakur <shashankt2004@gmail.com>
Shuo Chen <chenshuo@chenshuo.com>
Staffan Tjernstrom <staffantj@gmail.com>
Steinar H. Gunderson <sgunderson@bigfoot.com>
+103
View File
@@ -0,0 +1,103 @@
load("@rules_cc//cc:defs.bzl", "cc_library")
licenses(["notice"])
COPTS = [
"-pedantic",
"-pedantic-errors",
"-std=c++17",
"-Wall",
"-Wconversion",
"-Wextra",
"-Wshadow",
# "-Wshorten-64-to-32",
"-Wfloat-equal",
"-Wformat=2",
"-fstrict-aliasing",
## assert() are used a lot in tests upstream, which may be optimised out leading to
## unused-variable warning.
"-Wno-unused-variable",
"-Werror=old-style-cast",
]
MSVC_COPTS = [
"/std:c++17",
]
config_setting(
name = "windows",
constraint_values = ["@platforms//os:windows"],
visibility = [":__subpackages__"],
)
config_setting(
name = "perfcounters",
define_values = {
"pfm": "1",
},
visibility = [":__subpackages__"],
)
cc_library(
name = "benchmark",
srcs = glob(
[
"src/*.cc",
"src/*.h",
],
exclude = ["src/benchmark_main.cc"],
),
hdrs = [
"include/benchmark/benchmark.h",
"include/benchmark/export.h",
],
copts = select({
":windows": MSVC_COPTS,
"//conditions:default": COPTS,
}),
defines = [
"BENCHMARK_STATIC_DEFINE",
"BENCHMARK_VERSION=\\\"" + (module_version() if module_version() != None else "") + "\\\"",
] + select({
":perfcounters": ["HAVE_LIBPFM"],
"//conditions:default": [],
}),
includes = ["include"],
linkopts = select({
":windows": ["-DEFAULTLIB:shlwapi.lib"],
"//conditions:default": ["-pthread"],
}),
# Only static linking is allowed; no .so will be produced.
# Using `defines` (i.e. not `local_defines`) means that no
# dependent rules need to bother about defining the macro.
linkstatic = True,
local_defines = [
# Turn on Large-file Support
"_FILE_OFFSET_BITS=64",
"_LARGEFILE64_SOURCE",
"_LARGEFILE_SOURCE",
],
visibility = ["//visibility:public"],
deps = select({
":perfcounters": ["@libpfm"],
"//conditions:default": [],
}),
)
cc_library(
name = "benchmark_main",
srcs = ["src/benchmark_main.cc"],
hdrs = [
"include/benchmark/benchmark.h",
"include/benchmark/export.h",
],
includes = ["include"],
visibility = ["//visibility:public"],
deps = [":benchmark"],
)
cc_library(
name = "benchmark_internal_headers",
hdrs = glob(["src/*.h"]),
visibility = ["//test:__pkg__"],
)
+17 -7
View File
@@ -1,7 +1,7 @@
# Require CMake 3.10. If available, use the policies up to CMake 3.22.
cmake_minimum_required (VERSION 3.13...3.22)
project (benchmark VERSION 1.9.4 LANGUAGES CXX)
project (benchmark VERSION 1.9.5 LANGUAGES CXX)
option(BENCHMARK_ENABLE_TESTING "Enable testing of the benchmark library." ON)
option(BENCHMARK_ENABLE_EXCEPTIONS "Enable the use of exceptions in the benchmark library." ON)
@@ -29,6 +29,7 @@ endif()
option(BENCHMARK_ENABLE_INSTALL "Enable installation of benchmark. (Projects embedding benchmark may want to turn this OFF.)" ON)
option(BENCHMARK_ENABLE_DOXYGEN "Build documentation with Doxygen." OFF)
option(BENCHMARK_INSTALL_DOCS "Enable installation of documentation." ON)
option(BENCHMARK_INSTALL_TOOLS "Enable installation of tools." ON)
# Allow unmet dependencies to be met using CMake's ExternalProject mechanics, which
# may require downloading the source code.
@@ -196,6 +197,7 @@ else()
add_cxx_compiler_flag(-Wfloat-equal)
add_cxx_compiler_flag(-Wold-style-cast)
add_cxx_compiler_flag(-Wconversion)
add_cxx_compiler_flag(-Wformat=2)
if(BENCHMARK_ENABLE_WERROR)
add_cxx_compiler_flag(-Werror)
endif()
@@ -216,6 +218,9 @@ else()
# See #631 for rationale.
add_cxx_compiler_flag(-wd1786)
add_cxx_compiler_flag(-fno-finite-math-only)
# ICC17u2: overloaded virtual function "benchmark::Fixture::SetUp" is only partially
# overridden (because of deprecated overload)
add_cxx_compiler_flag(-wd654)
endif()
# Disable deprecation warnings for release builds (when -Werror is enabled).
if(BENCHMARK_ENABLE_WERROR)
@@ -230,9 +235,7 @@ else()
add_cxx_compiler_flag(-Wstrict-aliasing)
endif()
endif()
# ICC17u2: overloaded virtual function "benchmark::Fixture::SetUp" is only partially overridden
# (because of deprecated overload)
add_cxx_compiler_flag(-wd654)
add_cxx_compiler_flag(-Wthread-safety)
if (HAVE_CXX_FLAG_WTHREAD_SAFETY)
cxx_feature_check(THREAD_SAFETY_ATTRIBUTES "-DINCLUDE_DIRECTORIES=${PROJECT_SOURCE_DIR}/include")
@@ -307,10 +310,17 @@ if (BENCHMARK_USE_LIBCXX)
endif(BENCHMARK_USE_LIBCXX)
# C++ feature checks
# Determine the correct regular expression engine to use
# Determine the correct regular expression engine to use. First compatible engine found is used.
cxx_feature_check(STD_REGEX)
cxx_feature_check(GNU_POSIX_REGEX)
cxx_feature_check(POSIX_REGEX)
if(NOT HAVE_STD_REGEX)
cxx_feature_check(GNU_POSIX_REGEX)
endif()
if(NOT HAVE_STD_REGEX AND NOT HAVE_GNU_POSIX_REGEX)
cxx_feature_check(POSIX_REGEX)
endif()
if(NOT HAVE_STD_REGEX AND NOT HAVE_GNU_POSIX_REGEX AND NOT HAVE_POSIX_REGEX)
message(FATAL_ERROR "Failed to determine the source files for the regular expression backend")
endif()
+4
View File
@@ -67,6 +67,7 @@ Jussi Knuuttila <jussi.knuuttila@gmail.com>
Kaito Udagawa <umireon@gmail.com>
Kai Wolf <kai.wolf@gmail.com>
Kishan Kumar <kumar.kishan@outlook.com>
Kostiantyn Lazukin <konstantin.lazukin@gmail.com>
Lei Xu <eddyxu@gmail.com>
Marcel Jacobse <mjacobse@uni-bremen.de>
Matt Clarkson <mattyclarkson@gmail.com>
@@ -76,10 +77,12 @@ Min-Yih Hsu <yihshyng223@gmail.com>
Nick Hutchinson <nshutchinson@gmail.com>
Norman Heino <norman.heino@gmail.com>
Oleksandr Sochka <sasha.sochka@gmail.com>
Olga Fadeeva <olga.kiselik@gmail.com>
Ori Livneh <ori.livneh@gmail.com>
Pascal Leroy <phl@google.com>
Paul Redmond <paul.redmond@gmail.com>
Pierre Phaneuf <pphaneuf@google.com>
Prithvi Rao <ee22b024@smail.iitm.ac.in>
Radoslav Yovchev <radoslav.tm@gmail.com>
Raghu Raja <raghu@enfabrica.net>
Rainer Orth <ro@cebitec.uni-bielefeld.de>
@@ -88,6 +91,7 @@ Ray Glover <ray.glover@uk.ibm.com>
Robert Guo <robert.guo@mongodb.com>
Roman Lebedev <lebedev.ri@gmail.com>
Sayan Bhattacharjee <aero.sayan@gmail.com>
Shashank Thakur <shashankt2004@gmail.com>
Shuo Chen <chenshuo@chenshuo.com>
Steven Wan <wan.yu@ibm.com>
Tobias Schmidt <tobias.schmidt@in.tum.de>
+3 -3
View File
@@ -8,9 +8,9 @@ third_party {
type: "Git"
value: "https://github.com/google/benchmark"
primary_source: true
version: "1.9.4"
version: "1.9.5"
}
version: "1.9.4"
last_upgrade_date { year: 2025 month: 10 day: 23 }
version: "1.9.5"
last_upgrade_date { year: 2026 month: 2 day: 9 }
license_type: PERMISSIVE
}
+2 -2
View File
@@ -1,6 +1,6 @@
module(
name = "google_benchmark",
version = "1.9.4",
version = "1.9.5",
)
bazel_dep(name = "bazel_skylib", version = "1.7.1")
@@ -38,4 +38,4 @@ use_repo(pip, "tools_pip_deps")
# -- bazel_dep definitions -- #
bazel_dep(name = "nanobind_bazel", version = "2.7.0", dev_dependency = True)
bazel_dep(name = "nanobind_bazel", version = "2.9.2", dev_dependency = True)
+1 -1
View File
@@ -2,9 +2,9 @@
[![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)
[![bazel](https://github.com/google/benchmark/actions/workflows/bazel.yml/badge.svg)](https://github.com/google/benchmark/actions/workflows/bazel.yml)
[![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)
[![Coverage Status](https://coveralls.io/repos/google/benchmark/badge.svg)](https://coveralls.io/r/google/benchmark)
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/google/benchmark/badge)](https://securityscorecards.dev/viewer/?uri=github.com/google/benchmark)
[![Discord](https://discordapp.com/api/guilds/1125694995928719494/widget.png?style=shield)](https://discord.gg/cz7UX7wKC2)
@@ -0,0 +1,34 @@
load("@nanobind_bazel//:build_defs.bzl", "nanobind_extension", "nanobind_stubgen")
load("@rules_python//python:defs.bzl", "py_library", "py_test")
py_library(
name = "google_benchmark",
srcs = ["__init__.py"],
visibility = ["//visibility:public"],
deps = [
":_benchmark",
],
)
nanobind_extension(
name = "_benchmark",
srcs = ["benchmark.cc"],
deps = ["//:benchmark"],
)
nanobind_stubgen(
name = "benchmark_stubgen",
marker_file = "bindings/python/google_benchmark/py.typed",
module = ":_benchmark",
)
py_test(
name = "example",
srcs = ["example.py"],
python_version = "PY3",
srcs_version = "PY3",
visibility = ["//visibility:public"],
deps = [
":google_benchmark",
],
)
@@ -0,0 +1,136 @@
# Copyright 2020 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Python benchmarking utilities.
Example usage:
import google_benchmark as benchmark
@benchmark.register
def my_benchmark(state):
... # Code executed outside `while` loop is not timed.
while state:
... # Code executed within `while` loop is timed.
if __name__ == '__main__':
benchmark.main()
"""
import atexit
from google_benchmark import _benchmark
from google_benchmark._benchmark import (
Counter as Counter,
State as State,
kMicrosecond as kMicrosecond,
kMillisecond as kMillisecond,
kNanosecond as kNanosecond,
kSecond as kSecond,
o1 as o1,
oAuto as oAuto,
oLambda as oLambda,
oLogN as oLogN,
oN as oN,
oNCubed as oNCubed,
oNLogN as oNLogN,
oNone as oNone,
oNSquared as oNSquared,
)
__version__ = "1.9.5"
class __OptionMaker:
"""A stateless class to collect benchmark options.
Collect all decorator calls like @option.range(start=0, limit=1<<5).
"""
class Options:
"""Pure data class to store options calls, along with the benchmarked
function."""
def __init__(self, func):
self.func = func
self.builder_calls = []
@classmethod
def make(cls, func_or_options):
"""Make Options from Options or the benchmarked function."""
if isinstance(func_or_options, cls.Options):
return func_or_options
return cls.Options(func_or_options)
def __getattr__(self, builder_name):
"""Append option call in the Options."""
# The function that get returned on @option.range(start=0, limit=1<<5).
def __builder_method(*args, **kwargs):
# The decorator that get called, either with the benchmared function
# or the previous Options
def __decorator(func_or_options):
options = self.make(func_or_options)
options.builder_calls.append((builder_name, args, kwargs))
# The decorator returns Options so it is not technically a
# decorator and needs a final call to @register
return options
return __decorator
return __builder_method
# Alias for nicer API.
# We have to instantiate an object, even if stateless, to be able to use
# __getattr__ on option.range
option = __OptionMaker()
def register(undefined=None, *, name=None):
"""Register function for benchmarking."""
if undefined is None:
# Decorator is called without parenthesis so we return a decorator
return lambda f: register(f, name=name)
# We have either the function to benchmark (simple case) or an instance of
# Options (@option._ case).
options = __OptionMaker.make(undefined)
if name is None:
name = options.func.__name__
# We register the benchmark and reproduce all the @option._ calls onto the
# benchmark builder pattern
benchmark = _benchmark.RegisterBenchmark(name, options.func)
for name, args, kwargs in options.builder_calls[::-1]:
getattr(benchmark, name)(*args, **kwargs)
# return the benchmarked function because the decorator does not modify it
return options.func
def main(argv: list[str] | None = None) -> None:
import sys
_benchmark.Initialize(argv or sys.argv)
return _benchmark.RunSpecifiedBenchmarks()
# FIXME: can we rerun with disabled ASLR?
# Methods for use with custom main function.
initialize = _benchmark.Initialize
run_benchmarks = _benchmark.RunSpecifiedBenchmarks
add_custom_context = _benchmark.AddCustomContext
atexit.register(_benchmark.ClearRegisteredBenchmarks)
@@ -0,0 +1,189 @@
// Benchmark for Python.
#include "benchmark/benchmark.h"
#include "nanobind/nanobind.h"
#include "nanobind/operators.h"
#include "nanobind/stl/bind_map.h"
#include "nanobind/stl/string.h"
#include "nanobind/stl/vector.h"
NB_MAKE_OPAQUE(benchmark::UserCounters);
namespace {
namespace nb = nanobind;
std::vector<std::string> Initialize(const std::vector<std::string>& argv) {
std::vector<char*> ptrs;
ptrs.reserve(argv.size());
for (auto& arg : argv) {
ptrs.push_back(const_cast<char*>(arg.c_str()));
}
if (!ptrs.empty()) {
// The `argv` pointers here become invalid when this function returns, but
// benchmark holds the pointer to `argv[0]`. We create a static copy of it
// so it persists, and replace the pointer below.
static std::string executable_name(argv[0]);
ptrs[0] = const_cast<char*>(executable_name.c_str());
}
int argc = static_cast<int>(argv.size());
benchmark::Initialize(&argc, ptrs.data());
std::vector<std::string> remaining_argv;
remaining_argv.reserve(argc);
for (int i = 0; i < argc; ++i) {
remaining_argv.emplace_back(ptrs[i]);
}
return remaining_argv;
}
benchmark::Benchmark* RegisterBenchmark(const std::string& name,
nb::callable f) {
return benchmark::RegisterBenchmark(
name, [f](benchmark::State& state) { f(&state); });
}
NB_MODULE(_benchmark, m) {
using benchmark::TimeUnit;
nb::enum_<TimeUnit>(m, "TimeUnit")
.value("kNanosecond", TimeUnit::kNanosecond)
.value("kMicrosecond", TimeUnit::kMicrosecond)
.value("kMillisecond", TimeUnit::kMillisecond)
.value("kSecond", TimeUnit::kSecond)
.export_values();
using benchmark::BigO;
nb::enum_<BigO>(m, "BigO")
.value("oNone", BigO::oNone)
.value("o1", BigO::o1)
.value("oN", BigO::oN)
.value("oNSquared", BigO::oNSquared)
.value("oNCubed", BigO::oNCubed)
.value("oLogN", BigO::oLogN)
.value("oNLogN", BigO::oNLogN)
.value("oAuto", BigO::oAuto)
.value("oLambda", BigO::oLambda)
.export_values();
using benchmark::Benchmark;
nb::class_<Benchmark>(m, "Benchmark")
// For methods returning a pointer to the current object, reference
// return policy is used to ask nanobind not to take ownership of the
// returned object and avoid calling delete on it.
// https://pybind11.readthedocs.io/en/stable/advanced/functions.html#return-value-policies
//
// For methods taking a const std::vector<...>&, a copy is created
// because a it is bound to a Python list.
// https://pybind11.readthedocs.io/en/stable/advanced/cast/stl.html
.def("unit", &Benchmark::Unit, nb::rv_policy::reference)
.def("arg", &Benchmark::Arg, nb::rv_policy::reference)
.def("args", &Benchmark::Args, nb::rv_policy::reference)
.def("range", &Benchmark::Range, nb::rv_policy::reference,
nb::arg("start"), nb::arg("limit"))
.def("dense_range", &Benchmark::DenseRange, nb::rv_policy::reference,
nb::arg("start"), nb::arg("limit"), nb::arg("step") = 1)
.def("ranges", &Benchmark::Ranges, nb::rv_policy::reference)
.def("args_product", &Benchmark::ArgsProduct, nb::rv_policy::reference)
.def("arg_name", &Benchmark::ArgName, nb::rv_policy::reference)
.def("arg_names", &Benchmark::ArgNames, nb::rv_policy::reference)
.def("range_pair", &Benchmark::RangePair, nb::rv_policy::reference,
nb::arg("lo1"), nb::arg("hi1"), nb::arg("lo2"), nb::arg("hi2"))
.def("range_multiplier", &Benchmark::RangeMultiplier,
nb::rv_policy::reference)
.def("min_time", &Benchmark::MinTime, nb::rv_policy::reference)
.def("min_warmup_time", &Benchmark::MinWarmUpTime,
nb::rv_policy::reference)
.def("iterations", &Benchmark::Iterations, nb::rv_policy::reference)
.def("repetitions", &Benchmark::Repetitions, nb::rv_policy::reference)
.def("report_aggregates_only", &Benchmark::ReportAggregatesOnly,
nb::rv_policy::reference, nb::arg("value") = true)
.def("display_aggregates_only", &Benchmark::DisplayAggregatesOnly,
nb::rv_policy::reference, nb::arg("value") = true)
.def("measure_process_cpu_time", &Benchmark::MeasureProcessCPUTime,
nb::rv_policy::reference)
.def("use_real_time", &Benchmark::UseRealTime, nb::rv_policy::reference)
.def("use_manual_time", &Benchmark::UseManualTime,
nb::rv_policy::reference)
.def(
"complexity",
(Benchmark * (Benchmark::*)(benchmark::BigO)) & Benchmark::Complexity,
nb::rv_policy::reference, nb::arg("complexity") = benchmark::oAuto);
using benchmark::Counter;
nb::class_<Counter> py_counter(m, "Counter");
nb::enum_<Counter::Flags>(py_counter, "Flags", nb::is_arithmetic(),
nb::is_flag())
.value("kDefaults", Counter::Flags::kDefaults)
.value("kIsRate", Counter::Flags::kIsRate)
.value("kAvgThreads", Counter::Flags::kAvgThreads)
.value("kAvgThreadsRate", Counter::Flags::kAvgThreadsRate)
.value("kIsIterationInvariant", Counter::Flags::kIsIterationInvariant)
.value("kIsIterationInvariantRate",
Counter::Flags::kIsIterationInvariantRate)
.value("kAvgIterations", Counter::Flags::kAvgIterations)
.value("kAvgIterationsRate", Counter::Flags::kAvgIterationsRate)
.value("kInvert", Counter::Flags::kInvert)
.export_values();
nb::enum_<Counter::OneK>(py_counter, "OneK")
.value("kIs1000", Counter::OneK::kIs1000)
.value("kIs1024", Counter::OneK::kIs1024)
.export_values();
py_counter
.def(nb::init<double, Counter::Flags, Counter::OneK>(),
nb::arg("value") = 0., nb::arg("flags") = Counter::kDefaults,
nb::arg("k") = Counter::kIs1000)
.def("__init__",
([](Counter* c, double value) { new (c) Counter(value); }))
.def_rw("value", &Counter::value)
.def_rw("flags", &Counter::flags)
.def_rw("oneK", &Counter::oneK)
.def(nb::init_implicit<double>());
nb::implicitly_convertible<nb::int_, Counter>();
nb::bind_map<benchmark::UserCounters>(m, "UserCounters");
using benchmark::State;
nb::class_<State>(m, "State")
.def("__bool__", &State::KeepRunning)
.def_prop_ro("keep_running", &State::KeepRunning)
.def("pause_timing", &State::PauseTiming)
.def("resume_timing", &State::ResumeTiming)
.def("skip_with_error", &State::SkipWithError)
.def_prop_ro("error_occurred", &State::error_occurred)
.def("set_iteration_time", &State::SetIterationTime)
.def_prop_rw("bytes_processed", &State::bytes_processed,
&State::SetBytesProcessed)
.def_prop_rw("complexity_n", &State::complexity_length_n,
&State::SetComplexityN)
.def_prop_rw("items_processed", &State::items_processed,
&State::SetItemsProcessed)
.def("set_label", &State::SetLabel)
.def(
"range",
[](const State& state, std::size_t pos = 0) -> int64_t {
if (pos < state.range_size()) {
return state.range(pos);
}
throw nb::index_error("pos is out of range");
},
nb::arg("pos") = 0)
.def_prop_ro("iterations", &State::iterations)
.def_prop_ro("name", &State::name)
.def_rw("counters", &State::counters)
.def_prop_ro("thread_index", &State::thread_index)
.def_prop_ro("threads", &State::threads);
m.def("Initialize", Initialize);
m.def("RegisterBenchmark", RegisterBenchmark, nb::rv_policy::reference);
m.def("RunSpecifiedBenchmarks",
[]() { benchmark::RunSpecifiedBenchmarks(); });
m.def("ClearRegisteredBenchmarks", benchmark::ClearRegisteredBenchmarks);
m.def("AddCustomContext", benchmark::AddCustomContext, nb::arg("key"),
nb::arg("value"),
"Add a key-value pair to output as part of the context stanza in the "
"report.");
};
} // namespace
@@ -0,0 +1,142 @@
# Copyright 2020 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Example of Python using C++ benchmark framework.
To run this example, you must first install the `google_benchmark` Python
package.
To install using `setup.py`, download and extract the `google_benchmark` source.
In the extracted directory, execute:
python setup.py install
"""
import random
import sys
import time
import google_benchmark as benchmark
from google_benchmark import Counter
@benchmark.register
def empty(state):
while state:
pass
@benchmark.register
def sum_million(state):
while state:
sum(range(1_000_000))
@benchmark.register
def pause_timing(state):
"""Pause timing every iteration."""
while state:
# Construct a list of random ints every iteration without timing it
state.pause_timing()
random_list = [random.randint(0, 100) for _ in range(100)]
state.resume_timing()
# Time the in place sorting algorithm
random_list.sort()
@benchmark.register
def skipped(state):
if True: # Test some predicate here.
state.skip_with_error("some error")
return # NOTE: You must explicitly return, or benchmark will continue.
# Benchmark code would be here.
@benchmark.register
@benchmark.option.use_manual_time()
def manual_timing(state):
while state:
# Manually count Python CPU time
start = time.perf_counter() # perf_counter_ns() in Python 3.7+
# Something to benchmark
time.sleep(0.01)
end = time.perf_counter()
state.set_iteration_time(end - start)
@benchmark.register
def custom_counters(state):
"""Collect custom metric using benchmark.Counter."""
num_foo = 0.0
while state:
# Benchmark some code here
# Collect some custom metric named foo
num_foo += 0.13
# Automatic Counter from numbers.
state.counters["foo"] = num_foo
# Set a counter as a rate.
state.counters["foo_rate"] = Counter(num_foo, Counter.kIsRate)
# Set a counter as an inverse of rate.
state.counters["foo_inv_rate"] = Counter(
num_foo, Counter.kIsRate | Counter.kInvert
)
# Set a counter as a thread-average quantity.
state.counters["foo_avg"] = Counter(num_foo, Counter.kAvgThreads)
# There's also a combined flag:
state.counters["foo_avg_rate"] = Counter(num_foo, Counter.kAvgThreadsRate)
@benchmark.register
@benchmark.option.measure_process_cpu_time()
@benchmark.option.use_real_time()
def with_options(state):
while state:
sum(range(1_000_000))
@benchmark.register(name="sum_million_microseconds")
@benchmark.option.unit(benchmark.kMicrosecond)
def with_options2(state):
while state:
sum(range(1_000_000))
@benchmark.register
@benchmark.option.arg(100)
@benchmark.option.arg(1000)
def passing_argument(state):
while state:
sum(range(state.range(0)))
@benchmark.register
@benchmark.option.range(8, limit=8 << 10)
def using_range(state):
while state:
sum(range(state.range(0)))
@benchmark.register
@benchmark.option.range_multiplier(2)
@benchmark.option.range(1 << 10, 1 << 18)
@benchmark.option.complexity(benchmark.oN)
def computing_complexity(state):
while state:
sum(range(state.range(0)))
state.complexity_n = state.range(0)
if __name__ == "__main__":
benchmark.add_custom_context("python", sys.version)
benchmark.main()
+66 -48
View File
@@ -10,22 +10,35 @@
#
# include(CXXFeatureCheck)
# cxx_feature_check(STD_REGEX)
# Requires CMake 2.8.12+
# Requires CMake 3.13+
if(__cxx_feature_check)
return()
endif()
set(__cxx_feature_check INCLUDED)
option(CXXFEATURECHECK_DEBUG OFF)
option(CXXFEATURECHECK_DEBUG OFF "Enable debug messages for CXX feature checks")
function(cxx_feature_check FILE)
string(TOLOWER ${FILE} FILE)
string(TOUPPER ${FILE} VAR)
string(TOUPPER "HAVE_${VAR}" FEATURE)
if (DEFINED HAVE_${VAR})
set(HAVE_${VAR} 1 PARENT_SCOPE)
add_definitions(-DHAVE_${VAR})
function(cxx_feature_check_print log)
if(CXXFEATURECHECK_DEBUG)
message(STATUS "${log}")
endif()
endfunction()
function(cxx_feature_check FEATURE)
string(TOLOWER ${FEATURE} FILE)
string(TOUPPER HAVE_${FEATURE} VAR)
# Check if the variable is already defined to a true or false for a quick return.
# This allows users to predefine the variable to skip the check.
# Or, if the variable is already defined by a previous check, we skip the costly check.
if (DEFINED ${VAR})
if (${VAR})
cxx_feature_check_print("Feature ${FEATURE} already enabled.")
add_compile_definitions(${VAR})
else()
cxx_feature_check_print("Feature ${FEATURE} already disabled.")
endif()
return()
endif()
@@ -35,48 +48,53 @@ function(cxx_feature_check FILE)
list(APPEND FEATURE_CHECK_CMAKE_FLAGS ${ARGV1})
endif()
if (NOT DEFINED COMPILE_${FEATURE})
if(CMAKE_CROSSCOMPILING)
message(STATUS "Cross-compiling to test ${FEATURE}")
try_compile(COMPILE_${FEATURE}
${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
CMAKE_FLAGS ${FEATURE_CHECK_CMAKE_FLAGS}
LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES}
OUTPUT_VARIABLE COMPILE_OUTPUT_VAR)
if(COMPILE_${FEATURE})
message(WARNING
"If you see build failures due to cross compilation, try setting HAVE_${VAR} to 0")
set(RUN_${FEATURE} 0 CACHE INTERNAL "")
else()
set(RUN_${FEATURE} 1 CACHE INTERNAL "")
endif()
else()
message(STATUS "Compiling and running to test ${FEATURE}")
try_run(RUN_${FEATURE} COMPILE_${FEATURE}
${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
CMAKE_FLAGS ${FEATURE_CHECK_CMAKE_FLAGS}
LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES}
COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT_VAR)
if(CMAKE_CROSSCOMPILING)
cxx_feature_check_print("Cross-compiling to test ${FEATURE}")
try_compile(
COMPILE_STATUS
${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
CMAKE_FLAGS "${FEATURE_CHECK_CMAKE_FLAGS}"
LINK_LIBRARIES "${BENCHMARK_CXX_LIBRARIES}"
OUTPUT_VARIABLE COMPILE_OUTPUT_VAR
)
if(COMPILE_STATUS)
set(RUN_STATUS 0)
message(WARNING
"If you see build failures due to cross compilation, try setting ${VAR} to 0")
endif()
else()
cxx_feature_check_print("Compiling and running to test ${FEATURE}")
try_run(
RUN_STATUS
COMPILE_STATUS
${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
CMAKE_FLAGS "${FEATURE_CHECK_CMAKE_FLAGS}"
LINK_LIBRARIES "${BENCHMARK_CXX_LIBRARIES}"
COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT
RUN_OUTPUT_VARIABLE RUN_OUTPUT
)
endif()
if(RUN_${FEATURE} EQUAL 0)
if(COMPILE_STATUS AND RUN_STATUS EQUAL 0)
message(STATUS "Performing Test ${FEATURE} -- success")
set(HAVE_${VAR} 1 PARENT_SCOPE)
add_definitions(-DHAVE_${VAR})
else()
if(NOT COMPILE_${FEATURE})
if(CXXFEATURECHECK_DEBUG)
message(STATUS "Performing Test ${FEATURE} -- failed to compile: ${COMPILE_OUTPUT_VAR}")
else()
message(STATUS "Performing Test ${FEATURE} -- failed to compile")
endif()
else()
message(STATUS "Performing Test ${FEATURE} -- compiled but failed to run")
endif()
set(${VAR} TRUE CACHE BOOL "" FORCE)
add_compile_definitions(${VAR})
return()
endif()
set(${VAR} FALSE CACHE BOOL "" FORCE)
message(STATUS "Performing Test ${FEATURE} -- failed")
if(NOT COMPILE_STATUS)
cxx_feature_check_print("Compile Output: ${COMPILE_OUTPUT}")
else()
cxx_feature_check_print("Run Output: ${RUN_OUTPUT}")
endif()
endfunction()
+10 -5
View File
@@ -105,23 +105,28 @@ Linux workstation are:
1. Use the performance governor as [discussed
above](user_guide#disabling-cpu-frequency-scaling).
1. Disable processor boosting by:
2. Disable processor boosting by:
```sh
echo 0 | sudo tee /sys/devices/system/cpu/cpufreq/boost
```
See the Linux kernel's
[boost.txt](https://www.kernel.org/doc/Documentation/cpu-freq/boost.txt)
for more information.
2. Set the benchmark program's task affinity to a fixed cpu. For example:
3. Set the benchmark program's task affinity to a fixed cpu. For example:
```sh
taskset -c 0 ./mybenchmark
```
3. Disabling Hyperthreading/SMT. This can be done in the Bios or using the
4. Increase the program's scheduling priority to minimize context switches using `nice` or `chrt`:
```sh
sudo nice -n -20 ./mybenchmark
sudo chrt -f 80 ./mybenchmark
```
5. Disabling Hyperthreading/SMT. This can be done in the Bios or using the
`/sys` file system (see the LLVM project's [Benchmarking
tips](https://llvm.org/docs/Benchmarking.html)).
4. Close other programs that do non-trivial things based on timers, such as
6. Close other programs that do non-trivial things based on timers, such as
your web browser, desktop environment, etc.
5. Reduce the working set of your benchmark to fit within the L1 cache, but
7. Reduce the working set of your benchmark to fit within the L1 cache, but
do be aware that this may lead you to optimize for an unrealistic
situation.
+5 -5
View File
@@ -452,7 +452,7 @@ benchmark. The following example enumerates a dense range on one parameter,
and a sparse range on the second.
```c++
static void CustomArguments(benchmark::internal::Benchmark* b) {
static void CustomArguments(benchmark::Benchmark* b) {
for (int i = 0; i <= 10; ++i)
for (int j = 32; j <= 1024*1024; j *= 8)
b->Args({i, j});
@@ -749,10 +749,6 @@ and `Counter` values. The latter is a `double`-like class, via an implicit
conversion to `double&`. Thus you can use all of the standard arithmetic
assignment operators (`=,+=,-=,*=,/=`) to change the value of each counter.
In multithreaded benchmarks, each counter is set on the calling thread only.
When the benchmark finishes, the counters from each thread will be summed;
the resulting sum is the value which will be shown for the benchmark.
The `Counter` constructor accepts three parameters: the value as a `double`
; a bit flag which allows you to show counters as rates, and/or as per-thread
iteration, and/or as per-thread averages, and/or iteration invariants,
@@ -797,6 +793,10 @@ You can use `insert()` with `std::initializer_list`:
```
<!-- {% endraw %} -->
In multithreaded benchmarks, each counter is set on the calling thread only.
When the benchmark finishes, the counters from each thread will be summed.
Counters that are configured with `kIsRate`, will report the average rate across all threads, while `kAvgThreadsRate` counters will report the average rate per thread.
### Counter Reporting
When using the console reporter, by default, user counters are printed at
+102 -49
View File
@@ -103,7 +103,7 @@ BENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {128, 512}});
// arbitrary set of arguments to run the microbenchmark on.
// The following example enumerates a dense range on
// one parameter, and a sparse range on the second.
static void CustomArguments(benchmark::internal::Benchmark* b) {
static void CustomArguments(benchmark::Benchmark* b) {
for (int i = 0; i <= 10; ++i)
for (int j = 32; j <= 1024*1024; j *= 8)
b->Args({i, j});
@@ -171,7 +171,6 @@ BENCHMARK(BM_test)->Unit(benchmark::kMillisecond);
#include <cassert>
#include <cstddef>
#include <functional>
#include <initializer_list>
#include <iosfwd>
#include <limits>
#include <map>
@@ -239,6 +238,16 @@ BENCHMARK(BM_test)->Unit(benchmark::kMillisecond);
_Pragma("diagnostic push") \
_Pragma("diag_suppress deprecated_entity_with_custom_message")
#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma("diagnostic pop")
#elif defined(_MSC_VER)
#define BENCHMARK_BUILTIN_EXPECT(x, y) x
#define BENCHMARK_DEPRECATED_MSG(msg) __declspec(deprecated(msg))
#define BENCHMARK_WARNING_MSG(msg) \
__pragma(message(__FILE__ "(" BENCHMARK_INTERNAL_TOSTRING( \
__LINE__) ") : warning note: " msg))
#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
__pragma(warning(push)) \
__pragma(warning(disable : 4996))
#define BENCHMARK_RESTORE_DEPRECATED_WARNING __pragma(warning(pop))
#else
#define BENCHMARK_BUILTIN_EXPECT(x, y) x
#define BENCHMARK_DEPRECATED_MSG(msg)
@@ -476,10 +485,11 @@ void RegisterProfilerManager(ProfilerManager* profiler_manager);
// Add a key-value pair to output as part of the context stanza in the report.
BENCHMARK_EXPORT
void AddCustomContext(const std::string& key, const std::string& value);
void AddCustomContext(std::string key, std::string value);
class Benchmark;
namespace internal {
class Benchmark;
class BenchmarkImp;
class BenchmarkFamilies;
@@ -611,6 +621,17 @@ inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
_ReadWriteBarrier();
}
template <class Tp>
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
_ReadWriteBarrier();
}
template <class Tp>
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
_ReadWriteBarrier();
}
#else
template <class Tp>
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {
@@ -956,6 +977,8 @@ class BENCHMARK_EXPORT BENCHMARK_INTERNAL_CACHELINE_ALIGNED State {
BENCHMARK_ALWAYS_INLINE
std::string name() const { return name_; }
size_t range_size() const { return range_.size(); }
private:
// items we expect on the first cache line (ie 64 bytes of the struct)
// When total_iterations_ is 0, KeepRunning() and friends will return false.
@@ -1102,20 +1125,15 @@ struct ThreadRunnerBase {
virtual void RunThreads(const std::function<void(int)>& fn) = 0;
};
namespace internal {
// Define alias of ThreadRunner factory function type
using threadrunner_factory =
std::function<std::unique_ptr<ThreadRunnerBase>(int)>;
typedef void(Function)(State&);
// ------------------------------------------------------
// Benchmark registration object. The BENCHMARK() macro expands
// into an internal::Benchmark* object. Various methods can
// be called on this object to change the properties of the benchmark.
// Each method returns "this" so that multiple method calls can
// chained into one expression.
// Benchmark registration object. The BENCHMARK() macro expands into a
// Benchmark* object. Various methods can be called on this object to
// change the properties of the benchmark. Each method returns "this" so
// that multiple method calls can chained into one expression.
class BENCHMARK_EXPORT Benchmark {
public:
virtual ~Benchmark();
@@ -1206,7 +1224,7 @@ class BENCHMARK_EXPORT Benchmark {
// Pass this benchmark object to *func, which can customize
// the benchmark by calling various methods like Arg, Args,
// Threads, etc.
Benchmark* Apply(void (*custom_arguments)(Benchmark* benchmark));
Benchmark* Apply(const std::function<void(Benchmark* benchmark)>&);
// Set the range multiplier for non-dense range. If not called, the range
// multiplier kRangeMultiplier will be used.
@@ -1329,11 +1347,11 @@ class BENCHMARK_EXPORT Benchmark {
const char* GetArgName(int arg) const;
private:
friend class BenchmarkFamilies;
friend class BenchmarkInstance;
friend class internal::BenchmarkFamilies;
friend class internal::BenchmarkInstance;
std::string name_;
AggregationReportMode aggregation_report_mode_;
internal::AggregationReportMode aggregation_report_mode_;
std::vector<std::string> arg_names_; // Args for all benchmark runs
std::vector<std::vector<int64_t>> args_; // Args for all benchmark runs
@@ -1350,7 +1368,7 @@ class BENCHMARK_EXPORT Benchmark {
bool use_manual_time_;
BigO complexity_;
BigOFunc* complexity_lambda_;
std::vector<Statistics> statistics_;
std::vector<internal::Statistics> statistics_;
std::vector<int> thread_counts_;
callback_function setup_;
@@ -1361,17 +1379,28 @@ class BENCHMARK_EXPORT Benchmark {
BENCHMARK_DISALLOW_COPY_AND_ASSIGN(Benchmark);
};
namespace internal {
// clang-format off
typedef BENCHMARK_DEPRECATED_MSG("Use ::benchmark::Benchmark instead")
::benchmark::Benchmark Benchmark;
typedef BENCHMARK_DEPRECATED_MSG(
"Use ::benchmark::threadrunner_factory instead")
::benchmark::threadrunner_factory threadrunner_factory;
// clang-format on
typedef void(Function)(State&);
} // namespace internal
// Create and register a benchmark with the specified 'name' that invokes
// the specified functor 'fn'.
//
// RETURNS: A pointer to the registered benchmark.
internal::Benchmark* RegisterBenchmark(const std::string& name,
internal::Function* fn);
Benchmark* RegisterBenchmark(const std::string& name, internal::Function* fn);
template <class Lambda>
internal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn);
Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn);
// Remove all registered benchmarks. All pointers to previously registered
// benchmarks are invalidated.
@@ -1380,7 +1409,7 @@ BENCHMARK_EXPORT void ClearRegisteredBenchmarks();
namespace internal {
// The class used to hold all Benchmarks created from static function.
// (ie those created using the BENCHMARK(...) macros.
class BENCHMARK_EXPORT FunctionBenchmark : public Benchmark {
class BENCHMARK_EXPORT FunctionBenchmark : public benchmark::Benchmark {
public:
FunctionBenchmark(const std::string& name, Function* func)
: Benchmark(name), func_(func) {}
@@ -1392,7 +1421,7 @@ class BENCHMARK_EXPORT FunctionBenchmark : public Benchmark {
};
template <class Lambda>
class LambdaBenchmark : public Benchmark {
class LambdaBenchmark : public benchmark::Benchmark {
public:
void Run(State& st) override { lambda_(st); }
@@ -1406,15 +1435,15 @@ class LambdaBenchmark : public Benchmark {
};
} // namespace internal
inline internal::Benchmark* RegisterBenchmark(const std::string& name,
internal::Function* fn) {
inline Benchmark* RegisterBenchmark(const std::string& name,
internal::Function* fn) {
return internal::RegisterBenchmarkInternal(
::benchmark::internal::make_unique<internal::FunctionBenchmark>(name,
fn));
}
template <class Lambda>
internal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn) {
Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn) {
using BenchType =
internal::LambdaBenchmark<typename std::decay<Lambda>::type>;
return internal::RegisterBenchmarkInternal(
@@ -1423,16 +1452,16 @@ internal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn) {
}
template <class Lambda, class... Args>
internal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn,
Args&&... args) {
Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn,
Args&&... args) {
return benchmark::RegisterBenchmark(
name, [=](benchmark::State& st) { fn(st, args...); });
}
// The base class for all fixture tests.
class Fixture : public internal::Benchmark {
class Fixture : public Benchmark {
public:
Fixture() : internal::Benchmark("") {}
Fixture() : Benchmark("") {}
void Run(State& st) override {
this->SetUp(st);
@@ -1455,14 +1484,29 @@ class Fixture : public internal::Benchmark {
// ------------------------------------------------------
// Macro to register benchmarks
// clang-format off
#if defined(__clang__)
#define BENCHMARK_DISABLE_COUNTER_WARNING \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wunknown-warning-option\"") \
_Pragma("GCC diagnostic ignored \"-Wc2y-extensions\"")
#define BENCHMARK_RESTORE_COUNTER_WARNING _Pragma("GCC diagnostic pop")
#else
#define BENCHMARK_DISABLE_COUNTER_WARNING
#define BENCHMARK_RESTORE_COUNTER_WARNING
#endif
// clang-format on
// Check that __COUNTER__ is defined and that __COUNTER__ increases by 1
// every time it is expanded. X + 1 == X + 0 is used in case X is defined to be
// empty. If X is empty the expression becomes (+1 == +0).
BENCHMARK_DISABLE_COUNTER_WARNING
#if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0)
#define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__
#else
#define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__
#endif
BENCHMARK_RESTORE_COUNTER_WARNING
// Helpers for generating unique variable names
#define BENCHMARK_PRIVATE_NAME(...) \
@@ -1475,17 +1519,19 @@ class Fixture : public internal::Benchmark {
#define BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method) \
BaseClass##_##Method##_Benchmark
#define BENCHMARK_PRIVATE_DECLARE(n) \
/* NOLINTNEXTLINE(misc-use-anonymous-namespace) */ \
static ::benchmark::internal::Benchmark const* const BENCHMARK_PRIVATE_NAME( \
n) BENCHMARK_UNUSED
#define BENCHMARK_PRIVATE_DECLARE(n) \
BENCHMARK_DISABLE_COUNTER_WARNING \
/* NOLINTNEXTLINE(misc-use-anonymous-namespace) */ \
static ::benchmark::Benchmark const* const BENCHMARK_PRIVATE_NAME(n) \
BENCHMARK_RESTORE_COUNTER_WARNING BENCHMARK_UNUSED
#define BENCHMARK(...) \
BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
::benchmark::internal::make_unique< \
::benchmark::internal::FunctionBenchmark>(#__VA_ARGS__, \
__VA_ARGS__)))
#define BENCHMARK(...) \
BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
::benchmark::internal::make_unique< \
::benchmark::internal::FunctionBenchmark>( \
#__VA_ARGS__, \
static_cast<::benchmark::internal::Function*>(__VA_ARGS__))))
// Old-style macros
#define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a))
@@ -1526,21 +1572,25 @@ class Fixture : public internal::Benchmark {
BENCHMARK_PRIVATE_DECLARE(n) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
::benchmark::internal::make_unique< \
::benchmark::internal::FunctionBenchmark>(#n "<" #a ">", n<a>)))
::benchmark::internal::FunctionBenchmark>( \
#n "<" #a ">", \
static_cast<::benchmark::internal::Function*>(n<a>))))
#define BENCHMARK_TEMPLATE2(n, a, b) \
BENCHMARK_PRIVATE_DECLARE(n) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
::benchmark::internal::make_unique< \
::benchmark::internal::FunctionBenchmark>(#n "<" #a "," #b ">", \
n<a, b>)))
#define BENCHMARK_TEMPLATE2(n, a, b) \
BENCHMARK_PRIVATE_DECLARE(n) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
::benchmark::internal::make_unique< \
::benchmark::internal::FunctionBenchmark>( \
#n "<" #a "," #b ">", \
static_cast<::benchmark::internal::Function*>(n<a, b>))))
#define BENCHMARK_TEMPLATE(n, ...) \
BENCHMARK_PRIVATE_DECLARE(n) = \
(::benchmark::internal::RegisterBenchmarkInternal( \
::benchmark::internal::make_unique< \
::benchmark::internal::FunctionBenchmark>( \
#n "<" #__VA_ARGS__ ">", n<__VA_ARGS__>)))
#n "<" #__VA_ARGS__ ">", \
static_cast<::benchmark::internal::Function*>(n<__VA_ARGS__>))))
// This will register a benchmark for a templatized function,
// with the additional arguments specified by `...`.
@@ -1661,9 +1711,11 @@ class Fixture : public internal::Benchmark {
::benchmark::internal::make_unique<UniqueName>()))
#define BENCHMARK_TEMPLATE_INSTANTIATE_F(BaseClass, Method, ...) \
BENCHMARK_DISABLE_COUNTER_WARNING \
BENCHMARK_TEMPLATE_PRIVATE_INSTANTIATE_F( \
BaseClass, Method, BENCHMARK_PRIVATE_NAME(BaseClass##Method), \
__VA_ARGS__)
__VA_ARGS__) \
BENCHMARK_RESTORE_COUNTER_WARNING
// This macro will define and register a benchmark within a fixture class.
#define BENCHMARK_F(BaseClass, Method) \
@@ -1798,6 +1850,7 @@ class BENCHMARK_EXPORT BenchmarkReporter {
complexity(oNone),
complexity_lambda(),
complexity_n(0),
statistics(),
report_big_o(false),
report_rms(false),
allocs_per_iter(0.0) {}
+2 -3
View File
@@ -19,15 +19,14 @@ classifiers = [
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Software Development :: Testing",
"Topic :: System :: Benchmark",
]
dynamic = ["readme", "version"]
dependencies = ["absl-py>=0.7.1"]
[project.optional-dependencies]
[dependency-groups]
dev = ["pre-commit>=3.3.3"]
[project.urls]
+6 -1
View File
@@ -131,7 +131,12 @@ class BuildBazelExtension(build_ext.build_ext):
pkgname = "google_benchmark"
pythonroot = Path("bindings") / "python" / "google_benchmark"
srcdir = temp_path / "bazel-bin" / pythonroot
libdir = Path(self.build_lib) / pkgname
if not self.inplace:
libdir = Path(self.build_lib) / pkgname
else:
build_py = self.get_finalized_command("build_py")
libdir = Path(build_py.get_package_dir(pkgname))
for root, dirs, files in os.walk(srcdir, topdown=True):
# exclude runfiles directories and children.
dirs[:] = [d for d in dirs if "runfiles" not in d]
+22 -1
View File
@@ -67,7 +67,6 @@ endif()
# We need extra libraries on Solaris
if(${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
target_link_libraries(benchmark PRIVATE kstat)
set(BENCHMARK_PRIVATE_LINK_LIBRARIES -lkstat)
endif()
if (NOT BUILD_SHARED_LIBS)
@@ -109,6 +108,20 @@ write_basic_package_version_file(
"${version_config}" VERSION ${GENERIC_LIB_VERSION} COMPATIBILITY SameMajorVersion
)
# Derive private link libraries from target
if(NOT BUILD_SHARED_LIBS)
get_target_property(LINK_LIBS benchmark LINK_LIBRARIES)
if(LINK_LIBS)
set(BENCHMARK_PRIVATE_LINK_LIBRARIES "")
foreach(LIB IN LISTS LINK_LIBS)
if(NOT TARGET "${LIB}" AND LIB MATCHES "^[a-zA-Z0-9_.-]+$")
list(APPEND BENCHMARK_PRIVATE_LINK_LIBRARIES "-l${LIB}")
endif()
endforeach()
string(JOIN " " BENCHMARK_PRIVATE_LINK_LIBRARIES ${BENCHMARK_PRIVATE_LINK_LIBRARIES})
endif()
endif()
configure_file("${PROJECT_SOURCE_DIR}/cmake/benchmark.pc.in" "${pkg_config}" @ONLY)
configure_file("${PROJECT_SOURCE_DIR}/cmake/benchmark_main.pc.in" "${pkg_config_main}" @ONLY)
@@ -181,3 +194,11 @@ else()
DESTINATION ${CMAKE_INSTALL_DOCDIR})
endif()
endif()
set(CMAKE_INSTALL_PYTOOLSDIR "${CMAKE_INSTALL_DATADIR}/googlebenchmark/tools" CACHE PATH "")
if (BENCHMARK_ENABLE_INSTALL AND BENCHMARK_INSTALL_TOOLS)
install(
DIRECTORY "${PROJECT_SOURCE_DIR}/tools/"
DESTINATION ${CMAKE_INSTALL_PYTOOLSDIR})
endif()
+6 -2
View File
@@ -708,11 +708,12 @@ void RegisterProfilerManager(ProfilerManager* manager) {
internal::profiler_manager = manager;
}
void AddCustomContext(const std::string& key, const std::string& value) {
void AddCustomContext(std::string key, std::string value) {
if (internal::global_context == nullptr) {
internal::global_context = new std::map<std::string, std::string>();
}
if (!internal::global_context->emplace(key, value).second) {
if (!internal::global_context->emplace(std::move(key), std::move(value))
.second) {
std::cerr << "Failed to add custom context \"" << key << "\" as it already "
<< "exists with value \"" << value << "\"\n";
}
@@ -722,6 +723,7 @@ namespace internal {
void (*HelperPrintf)();
namespace {
void PrintUsageAndExit() {
HelperPrintf();
std::flush(std::cout);
@@ -810,6 +812,8 @@ void ParseCommandLineFlags(int* argc, char** argv) {
}
}
} // end namespace
int InitializeStreams() {
static std::ios_base::Init init;
return 0;
+2 -1
View File
@@ -7,7 +7,8 @@
namespace benchmark {
namespace internal {
BenchmarkInstance::BenchmarkInstance(Benchmark* benchmark, int family_idx,
BenchmarkInstance::BenchmarkInstance(benchmark::Benchmark* benchmark,
int family_idx,
int per_family_instance_idx,
const std::vector<int64_t>& args,
int thread_count)
+2 -2
View File
@@ -17,7 +17,7 @@ namespace internal {
// Information kept per benchmark we may want to run
class BenchmarkInstance {
public:
BenchmarkInstance(Benchmark* benchmark, int family_idx,
BenchmarkInstance(benchmark::Benchmark* benchmark, int family_idx,
int per_family_instance_idx,
const std::vector<int64_t>& args, int thread_count);
@@ -52,7 +52,7 @@ class BenchmarkInstance {
private:
BenchmarkName name_;
Benchmark& benchmark_;
benchmark::Benchmark& benchmark_;
const int family_index_;
const int per_family_instance_index_;
AggregationReportMode aggregation_report_mode_;
+28 -19
View File
@@ -75,7 +75,7 @@ class BenchmarkFamilies {
static BenchmarkFamilies* GetInstance();
// Registers a benchmark family and returns the index assigned to it.
size_t AddBenchmark(std::unique_ptr<Benchmark> family);
size_t AddBenchmark(std::unique_ptr<benchmark::Benchmark> family);
// Clear all registered benchmark families.
void ClearBenchmarks();
@@ -89,7 +89,7 @@ class BenchmarkFamilies {
private:
BenchmarkFamilies() {}
std::vector<std::unique_ptr<Benchmark>> families_;
std::vector<std::unique_ptr<benchmark::Benchmark>> families_;
Mutex mutex_;
};
@@ -98,7 +98,8 @@ BenchmarkFamilies* BenchmarkFamilies::GetInstance() {
return &instance;
}
size_t BenchmarkFamilies::AddBenchmark(std::unique_ptr<Benchmark> family) {
size_t BenchmarkFamilies::AddBenchmark(
std::unique_ptr<benchmark::Benchmark> family) {
MutexLock l(mutex_);
size_t index = families_.size();
families_.push_back(std::move(family));
@@ -135,7 +136,7 @@ bool BenchmarkFamilies::FindBenchmarks(
int next_family_index = 0;
MutexLock l(mutex_);
for (std::unique_ptr<Benchmark>& family : families_) {
for (std::unique_ptr<benchmark::Benchmark>& family : families_) {
int family_index = next_family_index;
int per_family_instance_index = 0;
@@ -179,7 +180,7 @@ bool BenchmarkFamilies::FindBenchmarks(
++per_family_instance_index;
// Only bump the next family index once we've estabilished that
// Only bump the next family index once we've established that
// at least one instance of this family will be run.
if (next_family_index == family_index) {
++next_family_index;
@@ -191,8 +192,9 @@ bool BenchmarkFamilies::FindBenchmarks(
return true;
}
Benchmark* RegisterBenchmarkInternal(std::unique_ptr<Benchmark> bench) {
Benchmark* bench_ptr = bench.get();
benchmark::Benchmark* RegisterBenchmarkInternal(
std::unique_ptr<benchmark::Benchmark> bench) {
benchmark::Benchmark* bench_ptr = bench.get();
BenchmarkFamilies* families = BenchmarkFamilies::GetInstance();
families->AddBenchmark(std::move(bench));
return bench_ptr;
@@ -206,13 +208,15 @@ bool FindBenchmarksInternal(const std::string& re,
return BenchmarkFamilies::GetInstance()->FindBenchmarks(re, benchmarks, Err);
}
} // end namespace internal
//=============================================================================//
// Benchmark
//=============================================================================//
Benchmark::Benchmark(const std::string& name)
: name_(name),
aggregation_report_mode_(ARM_Unspecified),
aggregation_report_mode_(internal::ARM_Unspecified),
time_unit_(GetDefaultTimeUnit()),
use_default_time_unit_(true),
range_multiplier_(kRangeMultiplier),
@@ -253,7 +257,7 @@ Benchmark* Benchmark::Unit(TimeUnit unit) {
Benchmark* Benchmark::Range(int64_t start, int64_t limit) {
BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);
std::vector<int64_t> arglist;
AddRange(&arglist, start, limit, range_multiplier_);
internal::AddRange(&arglist, start, limit, range_multiplier_);
for (int64_t i : arglist) {
args_.push_back({i});
@@ -266,8 +270,8 @@ Benchmark* Benchmark::Ranges(
BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast<int>(ranges.size()));
std::vector<std::vector<int64_t>> arglists(ranges.size());
for (std::size_t i = 0; i < ranges.size(); i++) {
AddRange(&arglists[i], ranges[i].first, ranges[i].second,
range_multiplier_);
internal::AddRange(&arglists[i], ranges[i].first, ranges[i].second,
range_multiplier_);
}
ArgsProduct(arglists);
@@ -330,7 +334,8 @@ Benchmark* Benchmark::Args(const std::vector<int64_t>& args) {
return this;
}
Benchmark* Benchmark::Apply(void (*custom_arguments)(Benchmark* benchmark)) {
Benchmark* Benchmark::Apply(
const std::function<void(Benchmark* benchmark)>& custom_arguments) {
custom_arguments(this);
return this;
}
@@ -381,8 +386,8 @@ Benchmark* Benchmark::MinWarmUpTime(double t) {
Benchmark* Benchmark::Iterations(IterationCount n) {
BM_CHECK(n > 0);
BM_CHECK(IsZero(min_time_));
BM_CHECK(IsZero(min_warmup_time_));
BM_CHECK(internal::IsZero(min_time_));
BM_CHECK(internal::IsZero(min_warmup_time_));
iterations_ = n;
return this;
}
@@ -394,21 +399,23 @@ Benchmark* Benchmark::Repetitions(int n) {
}
Benchmark* Benchmark::ReportAggregatesOnly(bool value) {
aggregation_report_mode_ = value ? ARM_ReportAggregatesOnly : ARM_Default;
aggregation_report_mode_ =
value ? internal::ARM_ReportAggregatesOnly : internal::ARM_Default;
return this;
}
Benchmark* Benchmark::DisplayAggregatesOnly(bool value) {
// If we were called, the report mode is no longer 'unspecified', in any case.
using internal::AggregationReportMode;
aggregation_report_mode_ = static_cast<AggregationReportMode>(
aggregation_report_mode_ | ARM_Default);
aggregation_report_mode_ | internal::ARM_Default);
if (value) {
aggregation_report_mode_ = static_cast<AggregationReportMode>(
aggregation_report_mode_ | ARM_DisplayReportAggregatesOnly);
aggregation_report_mode_ | internal::ARM_DisplayReportAggregatesOnly);
} else {
aggregation_report_mode_ = static_cast<AggregationReportMode>(
aggregation_report_mode_ & ~ARM_DisplayReportAggregatesOnly);
aggregation_report_mode_ & ~internal::ARM_DisplayReportAggregatesOnly);
}
return this;
@@ -462,7 +469,7 @@ Benchmark* Benchmark::ThreadRange(int min_threads, int max_threads) {
BM_CHECK_GT(min_threads, 0);
BM_CHECK_GE(max_threads, min_threads);
AddRange(&thread_counts_, min_threads, max_threads, 2);
internal::AddRange(&thread_counts_, min_threads, max_threads, 2);
return this;
}
@@ -514,6 +521,8 @@ TimeUnit Benchmark::GetTimeUnit() const {
return use_default_time_unit_ ? GetDefaultTimeUnit() : time_unit_;
}
namespace internal {
//=============================================================================//
// FunctionBenchmark
//=============================================================================//
+1
View File
@@ -3,6 +3,7 @@
#include <algorithm>
#include <limits>
#include <type_traits>
#include <vector>
#include "check.h"
+10 -4
View File
@@ -123,7 +123,12 @@ BenchmarkReporter::Run CreateRunReport(
: 0;
}
internal::Finish(&report.counters, results.iterations, seconds,
// The CPU time is the total time taken by all thread. If we used that as
// the denominator, we'd be calculating the rate per thread here. This is
// why we have to divide the total cpu_time by the number of threads for
// global counters to get a global rate.
const double thread_seconds = seconds / b.threads();
internal::Finish(&report.counters, results.iterations, thread_seconds,
b.threads());
}
return report;
@@ -191,7 +196,7 @@ class ThreadRunnerDefault : public ThreadRunnerBase {
explicit ThreadRunnerDefault(int num_threads)
: pool(static_cast<size_t>(num_threads - 1)) {}
void RunThreads(const std::function<void(int)>& fn) final {
void RunThreads(const std::function<void(int)>& fn) override final {
// Run all but one thread in separate threads
for (std::size_t ti = 0; ti < pool.size(); ++ti) {
pool[ti] = std::thread(fn, static_cast<int>(ti + 1));
@@ -212,7 +217,8 @@ class ThreadRunnerDefault : public ThreadRunnerBase {
};
std::unique_ptr<ThreadRunnerBase> GetThreadRunner(
const threadrunner_factory& userThreadRunnerFactory, int num_threads) {
const benchmark::threadrunner_factory& userThreadRunnerFactory,
int num_threads) {
return userThreadRunnerFactory
? userThreadRunnerFactory(num_threads)
: std::make_unique<ThreadRunnerDefault>(num_threads);
@@ -400,7 +406,7 @@ bool BenchmarkRunner::ShouldReportIterationResults(
}
double BenchmarkRunner::GetMinTimeToApply() const {
// In order to re-use functionality to run and measure benchmarks for running
// In order to reuse functionality to run and measure benchmarks for running
// a warmup phase of the benchmark, we need a way of telling whether to apply
// min_time or min_warmup_time. This function will figure out if we are in the
// warmup phase and therefore need to apply min_warmup_time or if we already
+6 -1
View File
@@ -5,6 +5,8 @@
#include <iostream>
#include <string>
#include "internal_macros.h"
namespace benchmark {
enum LogColor {
COLOR_DEFAULT,
@@ -17,11 +19,14 @@ enum LogColor {
COLOR_WHITE
};
PRINTF_FORMAT_STRING_FUNC(1, 0)
std::string FormatString(const char* msg, va_list args);
std::string FormatString(const char* msg, ...);
PRINTF_FORMAT_STRING_FUNC(1, 2) std::string FormatString(const char* msg, ...);
PRINTF_FORMAT_STRING_FUNC(3, 0)
void ColorPrintf(std::ostream& out, LogColor color, const char* fmt,
va_list args);
PRINTF_FORMAT_STRING_FUNC(3, 4)
void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, ...);
// Returns true if stdout appears to be a terminal that supports colored
+4
View File
@@ -179,6 +179,8 @@ std::map<std::string, std::string> KvPairsFromEnv(
return value;
}
namespace {
// Parses a string as a command line flag. The string should have
// the format "--flag=value". When def_optional is true, the "=value"
// part can be omitted.
@@ -217,6 +219,8 @@ const char* ParseFlagValue(const char* str, const char* flag,
return flag_end + 1;
}
} // end namespace
BENCHMARK_EXPORT
bool ParseBoolFlag(const char* str, const char* flag, bool* value) {
// Gets the value of the flag as a string.
+8 -1
View File
@@ -17,7 +17,6 @@
#include "complexity.h"
#include <algorithm>
#include <cmath>
#include "benchmark/benchmark.h"
@@ -25,6 +24,8 @@
namespace benchmark {
namespace {
// Internal function to calculate the different scalability forms
BigOFunc* FittingCurve(BigO complexity) {
switch (complexity) {
@@ -48,6 +49,8 @@ BigOFunc* FittingCurve(BigO complexity) {
}
}
} // end namespace
// Function to return an string for the calculated complexity
std::string GetBigOString(BigO complexity) {
switch (complexity) {
@@ -68,6 +71,8 @@ std::string GetBigOString(BigO complexity) {
}
}
namespace {
// Find the coefficient for the high-order term in the running time, by
// minimizing the sum of squares of relative error, for the fitting curve
// given by the lambda expression.
@@ -152,6 +157,8 @@ LeastSq MinimalLeastSq(const std::vector<ComplexityN>& n,
return best_fit;
}
} // end namespace
std::vector<BenchmarkReporter::Run> ComputeBigO(
const std::vector<BenchmarkReporter::Run>& reports) {
typedef BenchmarkReporter::Run Run;
+1
View File
@@ -97,6 +97,7 @@ void ConsoleReporter::ReportRuns(const std::vector<Run>& reports) {
}
}
PRINTF_FORMAT_STRING_FUNC(3, 4)
static void IgnoreColorPrint(std::ostream& out, LogColor /*unused*/,
const char* fmt, ...) {
va_list args;
+4
View File
@@ -17,6 +17,8 @@
namespace benchmark {
namespace internal {
namespace {
double Finish(Counter const& c, IterationCount iterations, double cpu_time,
double num_threads) {
double v = c.value;
@@ -39,6 +41,8 @@ double Finish(Counter const& c, IterationCount iterations, double cpu_time,
return v;
}
} // namespace
void Finish(UserCounters* l, IterationCount iterations, double cpu_time,
double num_threads) {
for (auto& c : *l) {
+2 -7
View File
@@ -12,29 +12,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <string>
#include <tuple>
#include <vector>
#include "benchmark/benchmark.h"
#include "check.h"
#include "complexity.h"
#include "string_util.h"
#include "timers.h"
// File format reference: http://edoceo.com/utilitas/csv-file-format.
namespace benchmark {
namespace {
std::vector<std::string> elements = {
const std::vector<const char*> elements = {
"name", "iterations", "real_time", "cpu_time",
"time_unit", "bytes_per_second", "items_per_second", "label",
"error_occurred", "error_message"};
} // namespace
std::string CsvEscape(const std::string& s) {
std::string tmp;
@@ -51,6 +45,7 @@ std::string CsvEscape(const std::string& s) {
}
return '"' + tmp + '"';
}
} // namespace
BENCHMARK_EXPORT
bool CSVReporter::ReportContext(const Context& context) {
+8 -2
View File
@@ -36,6 +36,9 @@
// declarations of some other intrinsics, breaking compilation.
// Therefore, we simply declare __rdtsc ourselves. See also
// http://connect.microsoft.com/VisualStudio/feedback/details/262047
//
// Note that MSVC defines the x64 preprocessor macros when building
// for Arm64EC, despite it using Arm64 assembly instructions.
#if defined(COMPILER_MSVC) && !defined(_M_IX86) && !defined(_M_ARM64) && \
!defined(_M_ARM64EC)
extern "C" uint64_t __rdtsc();
@@ -79,7 +82,10 @@ inline BENCHMARK_ALWAYS_INLINE int64_t Now() {
int64_t ret;
__asm__ volatile("rdtsc" : "=A"(ret));
return ret;
#elif defined(__x86_64__) || defined(__amd64__)
// Note that Clang, like MSVC, defines the x64 preprocessor macros when building
// for Arm64EC, despite it using Arm64 assembly instructions.
#elif (defined(__x86_64__) || defined(__amd64__)) && !defined(__arm64ec__)
uint64_t low, high;
__asm__ volatile("rdtsc" : "=a"(low), "=d"(high));
return static_cast<int64_t>((high << 32) | low);
@@ -139,7 +145,7 @@ inline BENCHMARK_ALWAYS_INLINE int64_t Now() {
struct timespec ts = {0, 0};
clock_gettime(CLOCK_MONOTONIC, &ts);
return static_cast<int64_t>(ts.tv_sec) * 1000000000 + ts.tv_nsec;
#elif defined(__aarch64__)
#elif defined(__aarch64__) || defined(__arm64ec__)
// System timer of ARMv8 runs at a different frequency than the CPU's.
// The frequency is fixed, typically in the range 1-50MHz. It can be
// read at CNTFRQ special register. We assume the OS has set up
+10
View File
@@ -106,6 +106,16 @@
#define BENCHMARK_MAYBE_UNUSED
#endif
#if defined(__GNUC__) || defined(__clang__)
#define PRINTF_FORMAT_STRING_FUNC(format_arg, first_idx) \
__attribute__((format(printf, format_arg, first_idx)))
#elif defined(__MINGW32__)
#define PRINTF_FORMAT_STRING_FUNC(format_arg, first_idx) \
__attribute__((format(__MINGW_PRINTF_FORMAT, format_arg, first_idx)))
#else
#define PRINTF_FORMAT_STRING_FUNC(format_arg, first_idx)
#endif
// clang-format on
#endif // BENCHMARK_INTERNAL_MACROS_H_
+3 -1
View File
@@ -81,7 +81,9 @@ std::string FormatKV(std::string const& key, bool value) {
std::string FormatKV(std::string const& key, int64_t value) {
std::stringstream ss;
ss << '"' << StrEscape(key) << "\": " << value;
// We really want to just dump the integer as-is,
// without the system locale interfering.
ss << '"' << StrEscape(key) << "\": " << std::to_string(value);
return ss.str();
}
+1 -1
View File
@@ -214,7 +214,7 @@ PerfCounters PerfCounters::Create(
// This should never happen but if it does, we give up on the
// entire batch as recovery would be a mess.
GetErrorLogInstance() << "***WARNING*** Failed to start counters. "
"Claring out all counters.\n";
"Clearing out all counters.\n";
// Close all performance counters
for (int id : counter_ids) {
+2
View File
@@ -15,6 +15,8 @@
#ifndef BENCHMARK_RE_H_
#define BENCHMARK_RE_H_
#include <vector>
#include "internal_macros.h"
// clang-format off
+3 -2
View File
@@ -112,13 +112,14 @@ std::string ToBinaryStringFullySpecified(double value, int precision,
return mantissa + ExponentToPrefix(exponent, one_k == Counter::kIs1024);
}
PRINTF_FORMAT_STRING_FUNC(1, 0)
std::string StrFormatImp(const char* msg, va_list args) {
// we might need a second shot at this, so pre-emptivly make a copy
va_list args_cp;
va_copy(args_cp, args);
// TODO(ericwf): use std::array for first attempt to avoid one memory
// allocation guess what the size might be
// Use std::array for first attempt to avoid one memory allocation guess what
// the size might be
std::array<char, 256> local_buff = {};
// 2015-10-08: vsnprintf is used instead of snd::vsnprintf due to a limitation
+1 -1
View File
@@ -461,7 +461,7 @@ std::string GetSystemName() {
DWCOUNT, NULL, 0, NULL, NULL);
str.resize(len);
WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, hostname, DWCOUNT, &str[0],
str.size(), NULL, NULL);
static_cast<int>(str.size()), NULL, NULL);
#endif
return str;
#elif defined(BENCHMARK_OS_QURT)
+135
View File
@@ -0,0 +1,135 @@
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
platform(
name = "windows",
constraint_values = [
"@platforms//os:windows",
],
)
TEST_COPTS = [
"-pedantic",
"-pedantic-errors",
"-std=c++17",
"-Wall",
"-Wconversion",
"-Wextra",
"-Wshadow",
# "-Wshorten-64-to-32",
"-Wfloat-equal",
"-fstrict-aliasing",
## assert() are used a lot in tests upstream, which may be optimised out leading to
## unused-variable warning.
"-Wno-unused-variable",
"-Werror=old-style-cast",
]
TEST_MSVC_OPTS = [
"/std:c++17",
]
# Some of the issues with DoNotOptimize only occur when optimization is enabled
PER_SRC_COPTS = {
"donotoptimize_test.cc": ["-O3"],
}
TEST_ARGS = ["--benchmark_min_time=0.01s"]
PER_SRC_TEST_ARGS = {
"user_counters_tabular_test.cc": ["--benchmark_counters_tabular=true"],
"repetitions_test.cc": [" --benchmark_repetitions=3"],
"spec_arg_test.cc": ["--benchmark_filter=BM_NotChosen"],
"spec_arg_verbosity_test.cc": ["--v=42"],
"complexity_test.cc": ["--benchmark_min_time=1000000x"],
}
cc_library(
name = "output_test_helper",
testonly = 1,
srcs = ["output_test_helper.cc"],
hdrs = ["output_test.h"],
copts = select({
"//:windows": TEST_MSVC_OPTS,
"//conditions:default": TEST_COPTS,
}),
deps = [
"//:benchmark",
"//:benchmark_internal_headers",
],
)
# Tests that use gtest. These rely on `gtest_main`.
[
cc_test(
name = test_src[:-len(".cc")],
size = "small",
srcs = [test_src],
copts = select({
"//:windows": TEST_MSVC_OPTS,
"//conditions:default": TEST_COPTS,
}) + PER_SRC_COPTS.get(test_src, []),
deps = [
"//:benchmark",
"//:benchmark_internal_headers",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)
for test_src in glob(["*_gtest.cc"])
]
# Tests that do not use gtest. These have their own `main` defined.
[
cc_test(
name = test_src[:-len(".cc")],
size = "small",
srcs = [test_src],
args = TEST_ARGS + PER_SRC_TEST_ARGS.get(test_src, []),
copts = select({
"//:windows": TEST_MSVC_OPTS,
"//conditions:default": TEST_COPTS,
}) + PER_SRC_COPTS.get(test_src, []),
deps = [
":output_test_helper",
"//:benchmark",
"//:benchmark_internal_headers",
],
# FIXME: Add support for assembly tests to bazel.
# See Issue #556
# https://github.com/google/benchmark/issues/556
)
for test_src in glob(
["*_test.cc"],
exclude = [
"*_assembly_test.cc",
"cxx11_test.cc",
"link_main_test.cc",
],
)
]
cc_test(
name = "cxx11_test",
size = "small",
srcs = ["cxx11_test.cc"],
copts = TEST_COPTS + ["-std=c++11"],
target_compatible_with = select({
"//:windows": ["@platforms//:incompatible"],
"//conditions:default": [],
}),
deps = [
":output_test_helper",
"//:benchmark_main",
],
)
cc_test(
name = "link_main_test",
size = "small",
srcs = ["link_main_test.cc"],
copts = select({
"//:windows": TEST_MSVC_OPTS,
"//conditions:default": TEST_COPTS,
}),
deps = ["//:benchmark_main"],
)
+6
View File
@@ -186,6 +186,9 @@ benchmark_add_test(NAME templated_fixture_method_test COMMAND templated_fixture_
compile_output_test(user_counters_test)
benchmark_add_test(NAME user_counters_test COMMAND user_counters_test --benchmark_min_time=0.01s)
compile_output_test(user_counters_threads_test)
benchmark_add_test(NAME user_counters_threads_test COMMAND user_counters_threads_test --benchmark_min_time=0.01s)
compile_output_test(perf_counters_test)
benchmark_add_test(NAME perf_counters_test COMMAND perf_counters_test --benchmark_min_time=0.01s --benchmark_perf_counters=CYCLES,INSTRUCTIONS)
@@ -219,6 +222,9 @@ benchmark_add_test(NAME profiler_manager_iterations COMMAND profiler_manager_ite
compile_output_test(complexity_test)
benchmark_add_test(NAME complexity_benchmark COMMAND complexity_test --benchmark_min_time=1000000x)
compile_output_test(locale_impermeability_test)
benchmark_add_test(NAME locale_impermeability_test COMMAND locale_impermeability_test)
###############################################################################
# GoogleTest Unit Tests
###############################################################################
+2
View File
@@ -3,6 +3,7 @@
#define BASIC_BENCHMARK_TEST(x) BENCHMARK(x)->Arg(8)->Arg(512)->Arg(8192)
namespace {
void BM_empty(benchmark::State& state) {
for (auto _ : state) {
auto iterations = static_cast<double>(state.iterations()) *
@@ -174,5 +175,6 @@ static_assert(
benchmark::State::StateIterator>::value_type,
typename benchmark::State::StateIterator::value_type>::value,
"");
} // end namespace
BENCHMARK_MAIN();
@@ -1,7 +1,6 @@
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
@@ -35,12 +34,12 @@ class TestReporter : public benchmark::ConsoleReporter {
std::vector<benchmark::IterationCount> iter_nums_;
};
} // end namespace
static void BM_MyBench(benchmark::State& state) {
void BM_MyBench(benchmark::State& state) {
for (auto s : state) {
}
}
} // end namespace
BENCHMARK(BM_MyBench);
int main(int argc, char** argv) {
@@ -60,14 +60,14 @@ void DoTestHelper(int* argc, const char** argv, double expected) {
assert(!min_times.empty() && AlmostEqual(min_times[0], expected));
}
} // end namespace
static void BM_MyBench(benchmark::State& state) {
void BM_MyBench(benchmark::State& state) {
for (auto s : state) {
}
}
BENCHMARK(BM_MyBench);
} // end namespace
int main(int argc, char** argv) {
benchmark::MaybeReenterWithoutASLR(argc, argv);
@@ -1,13 +1,13 @@
#include "benchmark/benchmark.h"
#include "gtest/gtest.h"
using benchmark::Benchmark;
using benchmark::BenchmarkReporter;
using benchmark::callback_function;
using benchmark::ClearRegisteredBenchmarks;
using benchmark::RegisterBenchmark;
using benchmark::RunSpecifiedBenchmarks;
using benchmark::State;
using benchmark::internal::Benchmark;
static int functor_called = 0;
struct Functor {
+7 -11
View File
@@ -2,8 +2,6 @@
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <limits>
#include <string>
#include "benchmark/benchmark.h"
@@ -48,19 +46,18 @@ static std::atomic<int> setup_call(0);
static std::atomic<int> teardown_call(0);
static std::atomic<int> func_call(0);
} // namespace concurrent
} // namespace
static void DoSetup2(const benchmark::State& state) {
void DoSetup2(const benchmark::State& state) {
concurrent::setup_call.fetch_add(1, std::memory_order_acquire);
assert(state.thread_index() == 0);
}
static void DoTeardown2(const benchmark::State& state) {
void DoTeardown2(const benchmark::State& state) {
concurrent::teardown_call.fetch_add(1, std::memory_order_acquire);
assert(state.thread_index() == 0);
}
static void BM_concurrent(benchmark::State& state) {
void BM_concurrent(benchmark::State& state) {
for (auto s : state) {
}
concurrent::func_call.fetch_add(1, std::memory_order_acquire);
@@ -75,12 +72,10 @@ BENCHMARK(BM_concurrent)
->Threads(15);
// Testing interaction with Fixture::Setup/Teardown
namespace {
namespace fixture_interaction {
int setup = 0;
int fixture_setup = 0;
} // namespace fixture_interaction
} // namespace
#define FIXTURE_BECHMARK_NAME MyFixture
@@ -98,7 +93,7 @@ BENCHMARK_F(FIXTURE_BECHMARK_NAME, BM_WithFixture)(benchmark::State& st) {
}
}
static void DoSetupWithFixture(const benchmark::State& /*unused*/) {
void DoSetupWithFixture(const benchmark::State& /*unused*/) {
fixture_interaction::setup++;
}
@@ -116,10 +111,10 @@ namespace repetitions {
int setup = 0;
}
static void DoSetupWithRepetitions(const benchmark::State& /*unused*/) {
void DoSetupWithRepetitions(const benchmark::State& /*unused*/) {
repetitions::setup++;
}
static void BM_WithRep(benchmark::State& state) {
void BM_WithRep(benchmark::State& state) {
for (auto _ : state) {
}
}
@@ -132,6 +127,7 @@ BENCHMARK(BM_WithRep)
->Setup(DoSetupWithRepetitions)
->Iterations(100)
->Repetitions(4);
} // namespace
int main(int argc, char** argv) {
benchmark::MaybeReenterWithoutASLR(argc, argv);
+15 -19
View File
@@ -8,9 +8,7 @@
#include <complex>
#include <cstdlib>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <mutex>
#include <optional>
#include <set>
@@ -56,9 +54,7 @@ std::mutex test_vector_mu;
std::optional<std::vector<int>> test_vector;
// NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)
} // end namespace
static void BM_Factorial(benchmark::State& state) {
void BM_Factorial(benchmark::State& state) {
int fac_42 = 0;
for (auto _ : state) {
fac_42 = Factorial(8);
@@ -71,7 +67,7 @@ static void BM_Factorial(benchmark::State& state) {
BENCHMARK(BM_Factorial);
BENCHMARK(BM_Factorial)->UseRealTime();
static void BM_CalculatePiRange(benchmark::State& state) {
void BM_CalculatePiRange(benchmark::State& state) {
double pi = 0.0;
for (auto _ : state) {
pi = CalculatePi(static_cast<int>(state.range(0)));
@@ -82,7 +78,7 @@ static void BM_CalculatePiRange(benchmark::State& state) {
}
BENCHMARK_RANGE(BM_CalculatePiRange, 1, 1024 * 1024);
static void BM_CalculatePi(benchmark::State& state) {
void BM_CalculatePi(benchmark::State& state) {
static const int depth = 1024;
for (auto _ : state) {
double pi = CalculatePi(static_cast<int>(depth));
@@ -93,7 +89,7 @@ BENCHMARK(BM_CalculatePi)->Threads(8);
BENCHMARK(BM_CalculatePi)->ThreadRange(1, 32);
BENCHMARK(BM_CalculatePi)->ThreadPerCpu();
static void BM_SetInsert(benchmark::State& state) {
void BM_SetInsert(benchmark::State& state) {
std::set<int64_t> data;
for (auto _ : state) {
state.PauseTiming();
@@ -115,7 +111,7 @@ BENCHMARK(BM_SetInsert)->Ranges({{1 << 10, 8 << 10}, {128, 512}});
template <typename Container,
typename ValueType = typename Container::value_type>
static void BM_Sequential(benchmark::State& state) {
void BM_Sequential(benchmark::State& state) {
ValueType v = 42;
for (auto _ : state) {
Container c;
@@ -133,7 +129,7 @@ BENCHMARK_TEMPLATE(BM_Sequential, std::list<int>)->Range(1 << 0, 1 << 10);
// Test the variadic version of BENCHMARK_TEMPLATE in C++11 and beyond.
BENCHMARK_TEMPLATE(BM_Sequential, std::vector<int>, int)->Arg(512);
static void BM_StringCompare(benchmark::State& state) {
void BM_StringCompare(benchmark::State& state) {
size_t len = static_cast<size_t>(state.range(0));
std::string s1(len, '-');
std::string s2(len, '-');
@@ -144,7 +140,7 @@ static void BM_StringCompare(benchmark::State& state) {
}
BENCHMARK(BM_StringCompare)->Range(1, 1 << 20);
static void BM_SetupTeardown(benchmark::State& state) {
void BM_SetupTeardown(benchmark::State& state) {
if (state.thread_index() == 0) {
// No need to lock test_vector_mu here as this is running single-threaded.
test_vector = std::vector<int>();
@@ -165,7 +161,7 @@ static void BM_SetupTeardown(benchmark::State& state) {
}
BENCHMARK(BM_SetupTeardown)->ThreadPerCpu();
static void BM_LongTest(benchmark::State& state) {
void BM_LongTest(benchmark::State& state) {
double tracker = 0.0;
for (auto _ : state) {
for (int i = 0; i < state.range(0); ++i) {
@@ -175,7 +171,7 @@ static void BM_LongTest(benchmark::State& state) {
}
BENCHMARK(BM_LongTest)->Range(1 << 16, 1 << 28);
static void BM_ParallelMemset(benchmark::State& state) {
void BM_ParallelMemset(benchmark::State& state) {
int64_t size = state.range(0) / static_cast<int64_t>(sizeof(int));
int thread_size = static_cast<int>(size) / state.threads();
int from = thread_size * state.thread_index();
@@ -199,7 +195,7 @@ static void BM_ParallelMemset(benchmark::State& state) {
}
BENCHMARK(BM_ParallelMemset)->Arg(10 << 20)->ThreadRange(1, 4);
static void BM_ManualTiming(benchmark::State& state) {
void BM_ManualTiming(benchmark::State& state) {
int64_t slept_for = 0;
int64_t microseconds = state.range(0);
std::chrono::duration<double, std::micro> sleep_duration{
@@ -263,7 +259,7 @@ void BM_template1_capture(benchmark::State& state, ExtraArgs&&... extra_args) {
BENCHMARK_TEMPLATE1_CAPTURE(BM_template1_capture, void, foo, 24UL);
BENCHMARK_CAPTURE(BM_template1_capture<void>, foo, 24UL);
static void BM_DenseThreadRanges(benchmark::State& st) {
void BM_DenseThreadRanges(benchmark::State& st) {
switch (st.range(0)) {
case 1:
assert(st.threads() == 1 || st.threads() == 2 || st.threads() == 3);
@@ -285,7 +281,7 @@ BENCHMARK(BM_DenseThreadRanges)->Arg(1)->DenseThreadRange(1, 3);
BENCHMARK(BM_DenseThreadRanges)->Arg(2)->DenseThreadRange(1, 4, 2);
BENCHMARK(BM_DenseThreadRanges)->Arg(3)->DenseThreadRange(5, 14, 3);
static void BM_BenchmarkName(benchmark::State& state) {
void BM_BenchmarkName(benchmark::State& state) {
for (auto _ : state) {
}
@@ -296,15 +292,15 @@ BENCHMARK(BM_BenchmarkName);
// regression test for #1446
template <typename type>
static void BM_templated_test(benchmark::State& state) {
void BM_templated_test(benchmark::State& state) {
for (auto _ : state) {
type created_string;
benchmark::DoNotOptimize(created_string);
}
}
static const auto BM_templated_test_double =
BM_templated_test<std::complex<double>>;
const auto BM_templated_test_double = BM_templated_test<std::complex<double>>;
BENCHMARK(BM_templated_test_double);
} // end namespace
BENCHMARK_MAIN();
+11 -13
View File
@@ -1,5 +1,4 @@
#undef NDEBUG
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdlib>
@@ -13,10 +12,10 @@ namespace {
#define ADD_COMPLEXITY_CASES(...) \
const int CONCAT(dummy, __LINE__) = AddComplexityTest(__VA_ARGS__)
int AddComplexityTest(const std::string &test_name,
const std::string &big_o_test_name,
const std::string &rms_test_name,
const std::string &big_o, int family_index) {
int AddComplexityTest(const std::string& test_name,
const std::string& big_o_test_name,
const std::string& rms_test_name,
const std::string& big_o, int family_index) {
SetSubstitutions({{"%name", test_name},
{"%bigo_name", big_o_test_name},
{"%rms_name", rms_test_name},
@@ -61,13 +60,11 @@ int AddComplexityTest(const std::string &test_name,
return 0;
}
} // end namespace
// ========================================================================= //
// --------------------------- Testing BigO O(1) --------------------------- //
// ========================================================================= //
void BM_Complexity_O1(benchmark::State &state) {
void BM_Complexity_O1(benchmark::State& state) {
for (auto _ : state) {
// This test requires a non-zero CPU time to avoid divide-by-zero
benchmark::DoNotOptimize(state.iterations());
@@ -116,7 +113,7 @@ ADD_COMPLEXITY_CASES(one_test_name, big_o_1_test_name, rms_o_1_test_name,
// --------------------------- Testing BigO O(N) --------------------------- //
// ========================================================================= //
void BM_Complexity_O_N(benchmark::State &state) {
void BM_Complexity_O_N(benchmark::State& state) {
for (auto _ : state) {
// This test requires a non-zero CPU time to avoid divide-by-zero
benchmark::DoNotOptimize(state.iterations());
@@ -173,8 +170,8 @@ ADD_COMPLEXITY_CASES(n_test_name, big_o_n_test_name, rms_o_n_test_name,
// ------------------------- Testing BigO O(NlgN) ------------------------- //
// ========================================================================= //
static const double kLog2E = 1.44269504088896340736;
static void BM_Complexity_O_N_log_N(benchmark::State &state) {
const double kLog2E = 1.44269504088896340736;
void BM_Complexity_O_N_log_N(benchmark::State& state) {
for (auto _ : state) {
// This test requires a non-zero CPU time to avoid divide-by-zero
benchmark::DoNotOptimize(state.iterations());
@@ -236,7 +233,7 @@ ADD_COMPLEXITY_CASES(n_lg_n_test_name, big_o_n_lg_n_test_name,
// -------- Testing formatting of Complexity with captured args ------------ //
// ========================================================================= //
void BM_ComplexityCaptureArgs(benchmark::State &state, int n) {
void BM_ComplexityCaptureArgs(benchmark::State& state, int n) {
for (auto _ : state) {
// This test requires a non-zero CPU time to avoid divide-by-zero
benchmark::DoNotOptimize(state.iterations());
@@ -264,12 +261,13 @@ const std::string complexity_capture_name =
ADD_COMPLEXITY_CASES(complexity_capture_name, complexity_capture_name + "_BigO",
complexity_capture_name + "_RMS", "N",
/*family_index=*/9);
} // end namespace
// ========================================================================= //
// --------------------------- TEST CASES END ------------------------------ //
// ========================================================================= //
int main(int argc, char *argv[]) {
int main(int argc, char* argv[]) {
benchmark::MaybeReenterWithoutASLR(argc, argv);
RunOutputTests(argc, argv);
}
+2
View File
@@ -17,6 +17,7 @@
#define TEST_HAS_NO_EXCEPTIONS
#endif
namespace {
void TestHandler() {
#ifndef TEST_HAS_NO_EXCEPTIONS
throw std::logic_error("");
@@ -84,6 +85,7 @@ void BM_diagnostic_test_keep_running(benchmark::State& state) {
called_once = true;
}
BENCHMARK(BM_diagnostic_test_keep_running);
} // end namespace
int main(int argc, char* argv[]) {
#ifdef NDEBUG
@@ -10,11 +10,13 @@
// reporter in the presence of DisplayAggregatesOnly().
// We do not care about console output, the normal tests check that already.
namespace {
void BM_SummaryRepeat(benchmark::State& state) {
for (auto _ : state) {
}
}
BENCHMARK(BM_SummaryRepeat)->Repetitions(3)->DisplayAggregatesOnly();
} // end namespace
int main(int argc, char* argv[]) {
benchmark::MaybeReenterWithoutASLR(argc, argv);
+4 -3
View File
@@ -2,6 +2,7 @@
#ifdef __clang__
#pragma clang diagnostic ignored "-Wreturn-type"
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#endif
BENCHMARK_DISABLE_DEPRECATED_WARNING
@@ -19,7 +20,7 @@ inline int Add42(int x) { return x + 42; }
struct NotTriviallyCopyable {
NotTriviallyCopyable();
explicit NotTriviallyCopyable(int x) : value(x) {}
NotTriviallyCopyable(NotTriviallyCopyable const &);
NotTriviallyCopyable(NotTriviallyCopyable const&);
int value;
};
@@ -185,7 +186,7 @@ extern "C" void test_pointer_const_lvalue() {
// CHECK-CLANG: movq %rax, -{{[0-9]+}}(%[[REG:[a-z]+]])
// CHECK: ret
int x = 42;
int *const xp = &x;
int* const xp = &x;
benchmark::DoNotOptimize(xp);
}
@@ -196,6 +197,6 @@ extern "C" void test_pointer_lvalue() {
// CHECK-CLANG: movq %rax, -{{[0-9]+}}(%[[REG:[a-z+]+]])
// CHECK: ret
int x = 42;
int *xp = &x;
int* xp = &x;
benchmark::DoNotOptimize(xp);
}
+6 -7
View File
@@ -37,37 +37,36 @@ class TestReporter : public benchmark::ConsoleReporter {
mutable int64_t max_family_index_;
};
} // end namespace
static void NoPrefix(benchmark::State& state) {
void NoPrefix(benchmark::State& state) {
for (auto _ : state) {
}
}
BENCHMARK(NoPrefix);
static void BM_Foo(benchmark::State& state) {
void BM_Foo(benchmark::State& state) {
for (auto _ : state) {
}
}
BENCHMARK(BM_Foo);
static void BM_Bar(benchmark::State& state) {
void BM_Bar(benchmark::State& state) {
for (auto _ : state) {
}
}
BENCHMARK(BM_Bar);
static void BM_FooBar(benchmark::State& state) {
void BM_FooBar(benchmark::State& state) {
for (auto _ : state) {
}
}
BENCHMARK(BM_FooBar);
static void BM_FooBa(benchmark::State& state) {
void BM_FooBa(benchmark::State& state) {
for (auto _ : state) {
}
}
BENCHMARK(BM_FooBa);
} // end namespace
int main(int argc, char** argv) {
benchmark::MaybeReenterWithoutASLR(argc, argv);
+4 -2
View File
@@ -8,8 +8,9 @@
#include "benchmark/benchmark.h"
#include "output_test.h"
static const std::chrono::duration<double, std::milli> time_frame(50);
static const double time_frame_in_sec(
namespace {
const std::chrono::duration<double, std::milli> time_frame(50);
const double time_frame_in_sec(
std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1, 1>>>(
time_frame)
.count());
@@ -178,6 +179,7 @@ BENCHMARK(BM_MainThreadAndWorkerThread)
->Threads(2)
->MeasureProcessCPUTime()
->UseManualTime();
} // end namespace
// ========================================================================= //
// ---------------------------- TEST CASES END ----------------------------- //
+2
View File
@@ -1,5 +1,6 @@
#include "benchmark/benchmark.h"
namespace {
void BM_empty(benchmark::State& state) {
for (auto _ : state) {
auto iterations = static_cast<double>(state.iterations()) *
@@ -8,3 +9,4 @@ void BM_empty(benchmark::State& state) {
}
}
BENCHMARK(BM_empty);
} // end namespace
@@ -0,0 +1,47 @@
#undef NDEBUG
#include <cassert>
#include <cmath>
#include <cstdlib>
#include "benchmark/benchmark.h"
#include "output_test.h"
namespace {
void BM_ostream(benchmark::State& state) {
#if !defined(__MINGW64__) || defined(__clang__)
// GCC-based versions of MINGW64 do not support locale manipulations,
// don't run the test under them.
std::locale::global(std::locale("en_US.UTF-8"));
#endif
while (state.KeepRunning()) {
state.SetIterationTime(1e-6);
}
}
BENCHMARK(BM_ostream)->UseManualTime()->Iterations(1000000);
ADD_CASES(TC_ConsoleOut, {{"^BM_ostream/iterations:1000000/manual_time"
" %console_report$"}});
ADD_CASES(TC_JSONOut,
{{"\"name\": \"BM_ostream/iterations:1000000/manual_time\",$"},
{"\"family_index\": 0,$", MR_Next},
{"\"per_family_instance_index\": 0,$", MR_Next},
{"\"run_name\": "
"\"BM_ostream/iterations:1000000/manual_time\",$",
MR_Next},
{"\"run_type\": \"iteration\",$", MR_Next},
{"\"repetitions\": 1,$", MR_Next},
{"\"repetition_index\": 0,$", MR_Next},
{"\"threads\": 1,$", MR_Next},
{"\"iterations\": 1000000,$", MR_Next},
{"\"real_time\": %float,$", MR_Next},
{"\"cpu_time\": %float,$", MR_Next},
{"\"time_unit\": \"ns\"$", MR_Next},
{"}", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_ostream/iterations:1000000/"
"manual_time\",1000000,%float,%float,ns,,,,,$"}});
} // end namespace
int main(int argc, char* argv[]) {
benchmark::MaybeReenterWithoutASLR(argc, argv);
RunOutputTests(argc, argv);
}
+2 -3
View File
@@ -13,10 +13,8 @@ std::map<int, int> ConstructRandomMap(int size) {
return m;
}
} // namespace
// Basic version.
static void BM_MapLookup(benchmark::State& state) {
void BM_MapLookup(benchmark::State& state) {
const int size = static_cast<int>(state.range(0));
std::map<int, int> m;
for (auto _ : state) {
@@ -31,6 +29,7 @@ static void BM_MapLookup(benchmark::State& state) {
state.SetItemsProcessed(state.iterations() * size);
}
BENCHMARK(BM_MapLookup)->Range(1 << 3, 1 << 12);
} // namespace
// Using fixtures.
class MapFixture : public ::benchmark::Fixture {
+2 -1
View File
@@ -1,9 +1,9 @@
#include <memory>
#include "../src/check.h"
#include "benchmark/benchmark.h"
#include "output_test.h"
namespace {
class TestMemoryManager : public benchmark::MemoryManager {
void Start() override {}
void Stop(Result& result) override {
@@ -20,6 +20,7 @@ void BM_empty(benchmark::State& state) {
}
}
BENCHMARK(BM_empty);
} // end namespace
ADD_CASES(TC_ConsoleOut, {{"^BM_empty %console_report$"}});
ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_empty\",$"},
+1 -1
View File
@@ -5,13 +5,13 @@
namespace {
using benchmark::Benchmark;
using benchmark::ClearRegisteredBenchmarks;
using benchmark::ConsoleReporter;
using benchmark::MemoryManager;
using benchmark::RegisterBenchmark;
using benchmark::RunSpecifiedBenchmarks;
using benchmark::State;
using benchmark::internal::Benchmark;
constexpr int N_REPETITIONS = 100;
constexpr int N_ITERATIONS = 1;
+3 -1
View File
@@ -5,6 +5,7 @@
#include "benchmark/benchmark.h"
namespace {
class MultipleRangesFixture : public ::benchmark::Fixture {
public:
MultipleRangesFixture()
@@ -87,10 +88,11 @@ void BM_CheckDefaultArgument(benchmark::State& state) {
}
BENCHMARK(BM_CheckDefaultArgument)->Ranges({{1, 5}, {6, 10}});
static void BM_MultipleRanges(benchmark::State& st) {
void BM_MultipleRanges(benchmark::State& st) {
for (auto _ : st) {
}
}
BENCHMARK(BM_MultipleRanges)->Ranges({{5, 5}, {6, 6}});
} // end namespace
BENCHMARK_MAIN();
+3 -1
View File
@@ -8,6 +8,7 @@
#endif
#include <cassert>
namespace {
void BM_basic(benchmark::State& state) {
for (auto _ : state) {
}
@@ -50,7 +51,7 @@ BENCHMARK(BM_basic)->RangeMultiplier(4)->Range(-8, 8);
BENCHMARK(BM_basic)->DenseRange(-2, 2, 1);
BENCHMARK(BM_basic)->Ranges({{-64, 1}, {-8, -1}});
void CustomArgs(benchmark::internal::Benchmark* b) {
void CustomArgs(benchmark::Benchmark* b) {
for (int i = 0; i < 10; ++i) {
b->Arg(i);
}
@@ -73,5 +74,6 @@ void BM_explicit_iteration_count(benchmark::State& state) {
assert(state.iterations() == 42);
}
BENCHMARK(BM_explicit_iteration_count)->Iterations(42);
} // end namespace
BENCHMARK_MAIN();
+9 -5
View File
@@ -209,12 +209,14 @@ class ResultsChecker {
std::vector<std::string> SplitCsv_(const std::string& line) const;
};
namespace {
// store the static ResultsChecker in a function to prevent initialization
// order problems
ResultsChecker& GetResultsChecker() {
static ResultsChecker rc;
return rc;
}
} // end namespace
// add a results checker for a benchmark
void ResultsChecker::Add(const std::string& entry_pattern,
@@ -489,18 +491,19 @@ int SubstrCnt(const std::string& haystack, const std::string& pat) {
return count;
}
static char ToHex(int ch) {
namespace {
char ToHex(int ch) {
return ch < 10 ? static_cast<char>('0' + ch)
: static_cast<char>('a' + (ch - 10));
}
static char RandomHexChar() {
char RandomHexChar() {
static std::mt19937 rd{std::random_device{}()};
static std::uniform_int_distribution<int> mrand{0, 15};
return ToHex(mrand(rd));
}
static std::string GetRandomFileName() {
std::string GetRandomFileName() {
std::string model = "test.%%%%%%";
for (auto& ch : model) {
if (ch == '%') {
@@ -510,12 +513,12 @@ static std::string GetRandomFileName() {
return model;
}
static bool FileExists(std::string const& name) {
bool FileExists(std::string const& name) {
std::ifstream in(name.c_str());
return in.good();
}
static std::string GetTempFileName() {
std::string GetTempFileName() {
// This function attempts to avoid race conditions where two tests
// create the same file at the same time. However, it still introduces races
// similar to tmpnam.
@@ -530,6 +533,7 @@ static std::string GetTempFileName() {
std::flush(std::cerr);
std::exit(1);
}
} // end namespace
std::string GetFileReporterOutput(int argc, char* argv[]) {
std::vector<char*> new_argv(argv, argv + argc);
+35
View File
@@ -0,0 +1,35 @@
#include "benchmark/benchmark.h"
namespace {
// Simulate an overloaded function name.
// This version does nothing and is just here to create ambiguity for
// MyOverloadedBenchmark.
BENCHMARK_UNUSED void MyOverloadedBenchmark() {}
// This is the actual benchmark function we want to register.
// It has the signature void(benchmark::State&) required by the library.
void MyOverloadedBenchmark(benchmark::State& state) {
for (auto _ : state) {
}
}
// This macro invocation should compile correctly if benchmark.h
// contains the fix (using static_cast), but would fail to compile
// if the benchmark name were ambiguous (e.g., when using + or no cast
// with an overloaded function).
BENCHMARK(MyOverloadedBenchmark);
// Also test BENCHMARK_TEMPLATE with an overloaded name.
template <int N>
void MyTemplatedOverloadedBenchmark() {}
template <int N>
void MyTemplatedOverloadedBenchmark(benchmark::State& state) {
for (auto _ : state) {
}
}
BENCHMARK_TEMPLATE(MyTemplatedOverloadedBenchmark, 1);
} // end namespace
BENCHMARK_MAIN();
+5 -3
View File
@@ -11,8 +11,9 @@ namespace benchmark {
BM_DECLARE_string(benchmark_perf_counters);
} // namespace benchmark
namespace {
static void BM_Simple(benchmark::State& state) {
void BM_Simple(benchmark::State& state) {
for (auto _ : state) {
auto iterations = double(state.iterations()) * double(state.iterations());
benchmark::DoNotOptimize(iterations);
@@ -66,17 +67,18 @@ static void CheckSimple(Results const& e) {
double withoutPauseResumeInstrCount = 0.0;
double withPauseResumeInstrCount = 0.0;
static void SaveInstrCountWithoutResume(Results const& e) {
void SaveInstrCountWithoutResume(Results const& e) {
withoutPauseResumeInstrCount = e.GetAs<double>("INSTRUCTIONS");
}
static void SaveInstrCountWithResume(Results const& e) {
void SaveInstrCountWithResume(Results const& e) {
withPauseResumeInstrCount = e.GetAs<double>("INSTRUCTIONS");
}
CHECK_BENCHMARK_RESULTS("BM_Simple", &CheckSimple);
CHECK_BENCHMARK_RESULTS("BM_WithoutPauseResume", &SaveInstrCountWithoutResume);
CHECK_BENCHMARK_RESULTS("BM_WithPauseResume", &SaveInstrCountWithResume);
} // end namespace
int main(int argc, char* argv[]) {
benchmark::MaybeReenterWithoutASLR(argc, argv);
@@ -25,14 +25,13 @@ class NullReporter : public benchmark::BenchmarkReporter {
void ReportRuns(const std::vector<Run>& /* report */) override {}
};
} // end namespace
static void BM_MyBench(benchmark::State& state) {
void BM_MyBench(benchmark::State& state) {
for (auto s : state) {
++iteration_count;
}
}
BENCHMARK(BM_MyBench);
} // end namespace
int main(int argc, char** argv) {
benchmark::MaybeReenterWithoutASLR(argc, argv);
+2
View File
@@ -6,6 +6,7 @@
#include "benchmark/benchmark.h"
#include "output_test.h"
namespace {
class TestProfilerManager : public benchmark::ProfilerManager {
public:
void AfterSetupStart() override { ++start_called; }
@@ -38,6 +39,7 @@ ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_empty\",$"},
{"\"time_unit\": \"ns\"$", MR_Next},
{"}", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_empty\",%csv_report$"}});
} // end namespace
int main(int argc, char* argv[]) {
benchmark::MaybeReenterWithoutASLR(argc, argv);
+2 -3
View File
@@ -56,9 +56,7 @@ int AddCases(std::initializer_list<TestCase> const& v) {
#define ADD_CASES(...) \
const int CONCAT(dummy, __LINE__) = AddCases({__VA_ARGS__})
} // end namespace
using ReturnVal = benchmark::internal::Benchmark const* const;
using ReturnVal = benchmark::Benchmark const* const;
//----------------------------------------------------------------------------//
// Test RegisterBenchmark with no additional arguments
@@ -182,6 +180,7 @@ void RunTestTwo() {
}
assert(EB == ExpectedResults.end());
}
} // end namespace
int main(int argc, char* argv[]) {
benchmark::MaybeReenterWithoutASLR(argc, argv);
+4 -2
View File
@@ -2,11 +2,12 @@
#include "benchmark/benchmark.h"
#include "output_test.h"
namespace {
// ========================================================================= //
// ------------------------ Testing Basic Output --------------------------- //
// ========================================================================= //
static void BM_ExplicitRepetitions(benchmark::State& state) {
void BM_ExplicitRepetitions(benchmark::State& state) {
for (auto _ : state) {
}
}
@@ -108,7 +109,7 @@ ADD_CASES(TC_CSVOut,
// ------------------------ Testing Basic Output --------------------------- //
// ========================================================================= //
static void BM_ImplicitRepetitions(benchmark::State& state) {
void BM_ImplicitRepetitions(benchmark::State& state) {
for (auto _ : state) {
}
}
@@ -206,6 +207,7 @@ ADD_CASES(TC_CSVOut, {{"^\"BM_ImplicitRepetitions\",%csv_report$"}});
ADD_CASES(TC_CSVOut, {{"^\"BM_ImplicitRepetitions_mean\",%csv_report$"}});
ADD_CASES(TC_CSVOut, {{"^\"BM_ImplicitRepetitions_median\",%csv_report$"}});
ADD_CASES(TC_CSVOut, {{"^\"BM_ImplicitRepetitions_stddev\",%csv_report$"}});
} // end namespace
// ========================================================================= //
// --------------------------- TEST CASES END ------------------------------ //
@@ -6,6 +6,7 @@
#include "benchmark/benchmark.h"
#include "output_test.h"
namespace {
// Ok this test is super ugly. We want to check what happens with the file
// reporter in the presence of ReportAggregatesOnly().
// We do not care about console output, the normal tests check that already.
@@ -15,6 +16,7 @@ void BM_SummaryRepeat(benchmark::State& state) {
}
}
BENCHMARK(BM_SummaryRepeat)->Repetitions(3)->ReportAggregatesOnly();
} // end namespace
int main(int argc, char* argv[]) {
benchmark::MaybeReenterWithoutASLR(argc, argv);
+3 -4
View File
@@ -1,11 +1,9 @@
#undef NDEBUG
#include <numeric>
#include <utility>
#include "benchmark/benchmark.h"
#include "output_test.h"
namespace {
// ========================================================================= //
// ---------------------- Testing Prologue Output -------------------------- //
// ========================================================================= //
@@ -13,7 +11,7 @@
ADD_CASES(TC_ConsoleOut, {{"^[-]+$", MR_Next},
{"^Benchmark %s Time %s CPU %s Iterations$", MR_Next},
{"^[-]+$", MR_Next}});
static int AddContextCases() {
int AddContextCases() {
AddCases(TC_ConsoleErr,
{
{"^%int-%int-%intT%int:%int:%int[-+]%int:%int$", MR_Default},
@@ -1128,6 +1126,7 @@ void BM_CSV_Format(benchmark::State& state) {
}
BENCHMARK(BM_CSV_Format);
ADD_CASES(TC_CSVOut, {{"^\"BM_CSV_Format\",,,,,,,,true,\"\"\"freedom\"\"\"$"}});
} // end namespace
// ========================================================================= //
// --------------------------- TEST CASES END ------------------------------ //
+10 -11
View File
@@ -62,8 +62,6 @@ int AddCases(const std::string& base_name,
#define CONCAT2(x, y) x##y
#define ADD_CASES(...) const int CONCAT(dummy, __LINE__) = AddCases(__VA_ARGS__)
} // end namespace
void BM_error_no_running(benchmark::State& state) {
state.SkipWithError("error message");
}
@@ -182,6 +180,16 @@ ADD_CASES("BM_error_while_paused", {{"/1/threads:1", true, "error message"},
{"/2/threads:4", false, ""},
{"/2/threads:8", false, ""}});
void BM_malformed(benchmark::State& /*unused*/) {
// NOTE: empty body wanted. No thing else.
}
BENCHMARK(BM_malformed);
ADD_CASES("BM_malformed",
{{"", true,
"The benchmark didn't run, nor was it explicitly skipped. Please "
"call 'SkipWithXXX` in your benchmark as appropriate."}});
} // end namespace
int main(int argc, char* argv[]) {
benchmark::MaybeReenterWithoutASLR(argc, argv);
benchmark::Initialize(&argc, argv);
@@ -201,12 +209,3 @@ int main(int argc, char* argv[]) {
return 0;
}
void BM_malformed(benchmark::State&) {
// NOTE: empty body wanted. No thing else.
}
BENCHMARK(BM_malformed);
ADD_CASES("BM_malformed",
{{"", true,
"The benchmark didn't run, nor was it explicitly skipped. Please "
"call 'SkipWithXXX` in your benchmark as appropriate."}});
+4 -4
View File
@@ -39,21 +39,21 @@ class TestReporter : public benchmark::ConsoleReporter {
std::vector<std::string> matched_functions;
};
} // end namespace
static void BM_NotChosen(benchmark::State& state) {
void BM_NotChosen(benchmark::State& state) {
assert(false && "SHOULD NOT BE CALLED");
for (auto _ : state) {
}
}
BENCHMARK(BM_NotChosen);
static void BM_Chosen(benchmark::State& state) {
void BM_Chosen(benchmark::State& state) {
for (auto _ : state) {
}
}
BENCHMARK(BM_Chosen);
} // end namespace
int main(int argc, char** argv) {
benchmark::MaybeReenterWithoutASLR(argc, argv);
+3 -1
View File
@@ -4,12 +4,14 @@
#include "benchmark/benchmark.h"
namespace {
// Tests that the user specified verbosity level can be get.
static void BM_Verbosity(benchmark::State& state) {
void BM_Verbosity(benchmark::State& state) {
for (auto _ : state) {
}
}
BENCHMARK(BM_Verbosity);
} // end namespace
int main(int argc, char** argv) {
benchmark::MaybeReenterWithoutASLR(argc, argv);
+1
View File
@@ -2,6 +2,7 @@
#ifdef __clang__
#pragma clang diagnostic ignored "-Wreturn-type"
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#endif
// clang-format off
+1 -1
View File
@@ -6,7 +6,7 @@ namespace internal {
namespace {
class DummyBenchmark : public Benchmark {
class DummyBenchmark : public benchmark::Benchmark {
public:
DummyBenchmark() : Benchmark("dummy") {}
void Run(State& /*state*/) override {}
+3 -1
View File
@@ -4,6 +4,7 @@
#include "benchmark/benchmark.h"
#include "output_test.h"
namespace {
// @todo: <jpmag> this checks the full output at once; the rule for
// CounterSet1 was failing because it was not matching "^[-]+$".
// @todo: <jpmag> check that the counters are vertically aligned.
@@ -417,7 +418,7 @@ ADD_CASES(TC_CSVOut, {{"^\"BM_CounterRates_Tabular/threads:%int\",%csv_report,"
// VS2013 does not allow this function to be passed as a lambda argument
// to CHECK_BENCHMARK_RESULTS()
void CheckTabularRate(Results const& e) {
double t = e.DurationCPUTime();
double t = e.DurationCPUTime() / e.NumThreads();
CHECK_FLOAT_COUNTER_VALUE(e, "Foo", EQ, 1. / t, 0.001);
CHECK_FLOAT_COUNTER_VALUE(e, "Bar", EQ, 2. / t, 0.001);
CHECK_FLOAT_COUNTER_VALUE(e, "Baz", EQ, 4. / t, 0.001);
@@ -555,6 +556,7 @@ void CheckSet2(Results const& e) {
CHECK_COUNTER_VALUE(e, int, "Baz", EQ, 40);
}
CHECK_BENCHMARK_RESULTS("BM_CounterSet2_Tabular", &CheckSet2);
} // end namespace
// ========================================================================= //
// --------------------------- TEST CASES END ------------------------------ //
+27 -5
View File
@@ -21,7 +21,7 @@ ADD_CASES(TC_CSVOut, {{"%csv_header,\"bar\",\"foo\""}});
// ========================================================================= //
// ------------------------- Simple Counters Output ------------------------ //
// ========================================================================= //
namespace {
void BM_Counters_Simple(benchmark::State& state) {
for (auto _ : state) {
}
@@ -56,6 +56,7 @@ void CheckSimple(Results const& e) {
CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. * its, 0.001);
}
CHECK_BENCHMARK_RESULTS("BM_Counters_Simple", &CheckSimple);
} // end namespace
// ========================================================================= //
// --------------------- Counters+Items+Bytes/s Output --------------------- //
@@ -63,7 +64,6 @@ CHECK_BENCHMARK_RESULTS("BM_Counters_Simple", &CheckSimple);
namespace {
int num_calls1 = 0;
}
void BM_Counters_WithBytesAndItemsPSec(benchmark::State& state) {
for (auto _ : state) {
// This test requires a non-zero CPU time to avoid divide-by-zero
@@ -112,11 +112,12 @@ void CheckBytesAndItemsPSec(Results const& e) {
}
CHECK_BENCHMARK_RESULTS("BM_Counters_WithBytesAndItemsPSec",
&CheckBytesAndItemsPSec);
} // end namespace
// ========================================================================= //
// ------------------------- Rate Counters Output -------------------------- //
// ========================================================================= //
namespace {
void BM_Counters_Rate(benchmark::State& state) {
for (auto _ : state) {
// This test requires a non-zero CPU time to avoid divide-by-zero
@@ -157,11 +158,13 @@ void CheckRate(Results const& e) {
CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / t, 0.001);
}
CHECK_BENCHMARK_RESULTS("BM_Counters_Rate", &CheckRate);
} // end namespace
// ========================================================================= //
// ----------------------- Inverted Counters Output ------------------------ //
// ========================================================================= //
namespace {
void BM_Invert(benchmark::State& state) {
for (auto _ : state) {
// This test requires a non-zero CPU time to avoid divide-by-zero
@@ -199,11 +202,13 @@ void CheckInvert(Results const& e) {
CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 0.0001, 0.0001);
}
CHECK_BENCHMARK_RESULTS("BM_Invert", &CheckInvert);
} // end namespace
// ========================================================================= //
// --------------------- InvertedRate Counters Output ---------------------- //
// ========================================================================= //
namespace {
void BM_Counters_InvertedRate(benchmark::State& state) {
for (auto _ : state) {
// This test requires a non-zero CPU time to avoid divide-by-zero
@@ -247,11 +252,13 @@ void CheckInvertedRate(Results const& e) {
CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, t / 8192.0, 0.001);
}
CHECK_BENCHMARK_RESULTS("BM_Counters_InvertedRate", &CheckInvertedRate);
} // end namespace
// ========================================================================= //
// ------------------------- Thread Counters Output ------------------------ //
// ========================================================================= //
namespace {
void BM_Counters_Threads(benchmark::State& state) {
for (auto _ : state) {
}
@@ -287,11 +294,13 @@ void CheckThreads(Results const& e) {
CHECK_COUNTER_VALUE(e, int, "bar", EQ, 2 * e.NumThreads());
}
CHECK_BENCHMARK_RESULTS("BM_Counters_Threads/threads:%int", &CheckThreads);
} // end namespace
// ========================================================================= //
// ---------------------- ThreadAvg Counters Output ------------------------ //
// ========================================================================= //
namespace {
void BM_Counters_AvgThreads(benchmark::State& state) {
for (auto _ : state) {
}
@@ -329,11 +338,13 @@ void CheckAvgThreads(Results const& e) {
}
CHECK_BENCHMARK_RESULTS("BM_Counters_AvgThreads/threads:%int",
&CheckAvgThreads);
} // end namespace
// ========================================================================= //
// ---------------------- ThreadAvg Counters Output ------------------------ //
// ========================================================================= //
namespace {
void BM_Counters_AvgThreadsRate(benchmark::State& state) {
for (auto _ : state) {
// This test requires a non-zero CPU time to avoid divide-by-zero
@@ -370,16 +381,20 @@ ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_AvgThreadsRate/"
// VS2013 does not allow this function to be passed as a lambda argument
// to CHECK_BENCHMARK_RESULTS()
void CheckAvgThreadsRate(Results const& e) {
CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. / e.DurationCPUTime(), 0.001);
CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / e.DurationCPUTime(), 0.001);
// this (and not real time) is the time used
double t = e.DurationCPUTime() / e.NumThreads();
CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. / t, 0.001);
CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / t, 0.001);
}
CHECK_BENCHMARK_RESULTS("BM_Counters_AvgThreadsRate/threads:%int",
&CheckAvgThreadsRate);
} // end namespace
// ========================================================================= //
// ------------------- IterationInvariant Counters Output ------------------ //
// ========================================================================= //
namespace {
void BM_Counters_IterationInvariant(benchmark::State& state) {
for (auto _ : state) {
}
@@ -418,11 +433,13 @@ void CheckIterationInvariant(Results const& e) {
}
CHECK_BENCHMARK_RESULTS("BM_Counters_IterationInvariant",
&CheckIterationInvariant);
} // end namespace
// ========================================================================= //
// ----------------- IterationInvariantRate Counters Output ---------------- //
// ========================================================================= //
namespace {
void BM_Counters_kIsIterationInvariantRate(benchmark::State& state) {
for (auto _ : state) {
// This test requires a non-zero CPU time to avoid divide-by-zero
@@ -469,11 +486,13 @@ void CheckIsIterationInvariantRate(Results const& e) {
}
CHECK_BENCHMARK_RESULTS("BM_Counters_kIsIterationInvariantRate",
&CheckIsIterationInvariantRate);
} // end namespace
// ========================================================================= //
// --------------------- AvgIterations Counters Output --------------------- //
// ========================================================================= //
namespace {
void BM_Counters_AvgIterations(benchmark::State& state) {
for (auto _ : state) {
}
@@ -511,11 +530,13 @@ void CheckAvgIterations(Results const& e) {
CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / its, 0.001);
}
CHECK_BENCHMARK_RESULTS("BM_Counters_AvgIterations", &CheckAvgIterations);
} // end namespace
// ========================================================================= //
// ------------------- AvgIterationsRate Counters Output ------------------- //
// ========================================================================= //
namespace {
void BM_Counters_kAvgIterationsRate(benchmark::State& state) {
for (auto _ : state) {
// This test requires a non-zero CPU time to avoid divide-by-zero
@@ -560,6 +581,7 @@ void CheckAvgIterationsRate(Results const& e) {
}
CHECK_BENCHMARK_RESULTS("BM_Counters_kAvgIterationsRate",
&CheckAvgIterationsRate);
} // end namespace
// ========================================================================= //
// --------------------------- TEST CASES END ------------------------------ //
@@ -4,6 +4,7 @@
#include "benchmark/benchmark.h"
#include "output_test.h"
namespace {
// ========================================================================= //
// ------------------------ Thousands Customisation ------------------------ //
// ========================================================================= //
@@ -179,6 +180,7 @@ void CheckThousands(Results const& e) {
CHECK_FLOAT_COUNTER_VALUE(e, "t4_1048576Base1024", EQ, 1024 * 1024, 0.0001);
}
CHECK_BENCHMARK_RESULTS("BM_Counters_Thousands", &CheckThousands);
} // end namespace
// ========================================================================= //
// --------------------------- TEST CASES END ------------------------------ //
+622
View File
@@ -0,0 +1,622 @@
#undef NDEBUG
#include "benchmark/benchmark.h"
#include "output_test.h"
// ========================================================================= //
// ---------------------- Testing Prologue Output -------------------------- //
// ========================================================================= //
// clang-format off
ADD_CASES(TC_ConsoleOut,
{{"^[-]+$", MR_Next},
{"^Benchmark %s Time %s CPU %s Iterations UserCounters...$", MR_Next},
{"^[-]+$", MR_Next}});
ADD_CASES(TC_CSVOut, {{"%csv_header,\"bar\",\"foo\""}});
// clang-format on
// ========================================================================= //
// ------------------------- Simple Counters Output ------------------------ //
// ========================================================================= //
namespace {
void BM_Counters_Simple(benchmark::State& state) {
for (auto _ : state) {
}
state.counters["foo"] = 1;
state.counters["bar"] = 2 * static_cast<double>(state.iterations());
}
BENCHMARK(BM_Counters_Simple)->ThreadRange(1, 8);
ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_Simple/threads:%int %console_report "
"bar=%hrfloat foo=%hrfloat$"}});
ADD_CASES(TC_JSONOut,
{{"\"name\": \"BM_Counters_Simple/threads:%int\",$"},
{"\"family_index\": 0,$", MR_Next},
{"\"per_family_instance_index\": 0,$", MR_Next},
{"\"run_name\": \"BM_Counters_Simple/threads:%int\",$", MR_Next},
{"\"run_type\": \"iteration\",$", MR_Next},
{"\"repetitions\": 1,$", MR_Next},
{"\"repetition_index\": 0,$", MR_Next},
{"\"threads\": %int,$", MR_Next},
{"\"iterations\": %int,$", MR_Next},
{"\"real_time\": %float,$", MR_Next},
{"\"cpu_time\": %float,$", MR_Next},
{"\"time_unit\": \"ns\",$", MR_Next},
{"\"bar\": %float,$", MR_Next},
{"\"foo\": %float$", MR_Next},
{"}", MR_Next}});
ADD_CASES(
TC_CSVOut,
{{"^\"BM_Counters_Simple/threads:%int\",%csv_report,%float,%float$"}});
// VS2013 does not allow this function to be passed as a lambda argument
// to CHECK_BENCHMARK_RESULTS()
void CheckSimple(Results const& e) {
double its = e.NumIterations();
CHECK_COUNTER_VALUE(e, int, "foo", EQ, 1 * e.NumThreads());
// check that the value of bar is within 0.1% of the expected value
CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. * its, 0.001);
}
CHECK_BENCHMARK_RESULTS("BM_Counters_Simple/threads:%int", &CheckSimple);
} // end namespace
// ========================================================================= //
// --------------------- Counters+Items+Bytes/s Output --------------------- //
// ========================================================================= //
namespace {
void BM_Counters_WithBytesAndItemsPSec(benchmark::State& state) {
for (auto _ : state) {
// This test requires a non-zero CPU time to avoid divide-by-zero
auto iterations = static_cast<double>(state.iterations()) *
static_cast<double>(state.iterations());
benchmark::DoNotOptimize(iterations);
}
state.counters["foo"] = 1;
state.SetBytesProcessed(364);
state.SetItemsProcessed(150);
}
BENCHMARK(BM_Counters_WithBytesAndItemsPSec)->ThreadRange(1, 8);
ADD_CASES(TC_ConsoleOut,
{{"^BM_Counters_WithBytesAndItemsPSec/threads:%int %console_report "
"bytes_per_second=%hrfloat/s "
"foo=%hrfloat items_per_second=%hrfloat/s$"}});
ADD_CASES(
TC_JSONOut,
{{"\"name\": \"BM_Counters_WithBytesAndItemsPSec/threads:%int\",$"},
{"\"family_index\": 1,$", MR_Next},
{"\"per_family_instance_index\": 0,$", MR_Next},
{"\"run_name\": \"BM_Counters_WithBytesAndItemsPSec/threads:%int\",$",
MR_Next},
{"\"run_type\": \"iteration\",$", MR_Next},
{"\"repetitions\": 1,$", MR_Next},
{"\"repetition_index\": 0,$", MR_Next},
{"\"threads\": %int,$", MR_Next},
{"\"iterations\": %int,$", MR_Next},
{"\"real_time\": %float,$", MR_Next},
{"\"cpu_time\": %float,$", MR_Next},
{"\"time_unit\": \"ns\",$", MR_Next},
{"\"bytes_per_second\": %float,$", MR_Next},
{"\"foo\": %float,$", MR_Next},
{"\"items_per_second\": %float$", MR_Next},
{"}", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_WithBytesAndItemsPSec/threads:%int\","
"%csv_bytes_items_report,,%float$"}});
// VS2013 does not allow this function to be passed as a lambda argument
// to CHECK_BENCHMARK_RESULTS()
void CheckBytesAndItemsPSec(Results const& e) {
// this (and not real time) is the time used
double t = e.DurationCPUTime() / e.NumThreads();
CHECK_COUNTER_VALUE(e, int, "foo", EQ, 1 * e.NumThreads());
// check that the values are within 0.1% of the expected values
CHECK_FLOAT_RESULT_VALUE(e, "bytes_per_second", EQ,
(364. * e.NumThreads()) / t, 0.001);
CHECK_FLOAT_RESULT_VALUE(e, "items_per_second", EQ,
(150. * e.NumThreads()) / t, 0.001);
}
CHECK_BENCHMARK_RESULTS("BM_Counters_WithBytesAndItemsPSec/threads:%int",
&CheckBytesAndItemsPSec);
} // end namespace
// ========================================================================= //
// ------------------------- Rate Counters Output -------------------------- //
// ========================================================================= //
namespace {
void BM_Counters_Rate(benchmark::State& state) {
for (auto _ : state) {
// This test requires a non-zero CPU time to avoid divide-by-zero
auto iterations = static_cast<double>(state.iterations()) *
static_cast<double>(state.iterations());
benchmark::DoNotOptimize(iterations);
}
namespace bm = benchmark;
state.counters["foo"] = bm::Counter{1, bm::Counter::kIsRate};
state.counters["bar"] = bm::Counter{2, bm::Counter::kIsRate};
}
BENCHMARK(BM_Counters_Rate)->ThreadRange(1, 8);
ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_Rate/threads:%int %console_report "
"bar=%hrfloat/s foo=%hrfloat/s$"}});
ADD_CASES(TC_JSONOut,
{{"\"name\": \"BM_Counters_Rate/threads:%int\",$"},
{"\"family_index\": 2,$", MR_Next},
{"\"per_family_instance_index\": 0,$", MR_Next},
{"\"run_name\": \"BM_Counters_Rate/threads:%int\",$", MR_Next},
{"\"run_type\": \"iteration\",$", MR_Next},
{"\"repetitions\": 1,$", MR_Next},
{"\"repetition_index\": 0,$", MR_Next},
{"\"threads\": %int,$", MR_Next},
{"\"iterations\": %int,$", MR_Next},
{"\"real_time\": %float,$", MR_Next},
{"\"cpu_time\": %float,$", MR_Next},
{"\"time_unit\": \"ns\",$", MR_Next},
{"\"bar\": %float,$", MR_Next},
{"\"foo\": %float$", MR_Next},
{"}", MR_Next}});
ADD_CASES(TC_CSVOut,
{{"^\"BM_Counters_Rate/threads:%int\",%csv_report,%float,%float$"}});
// VS2013 does not allow this function to be passed as a lambda argument
// to CHECK_BENCHMARK_RESULTS()
void CheckRate(Results const& e) {
// this (and not real time) is the time used
double t = e.DurationCPUTime() / e.NumThreads();
// check that the values are within 0.1% of the expected values
CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, (1. * e.NumThreads()) / t, 0.001);
CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, (2. * e.NumThreads()) / t, 0.001);
}
CHECK_BENCHMARK_RESULTS("BM_Counters_Rate/threads:%int", &CheckRate);
} // end namespace
// ========================================================================= //
// ----------------------- Inverted Counters Output ------------------------ //
// ========================================================================= //
namespace {
void BM_Invert(benchmark::State& state) {
for (auto _ : state) {
// This test requires a non-zero CPU time to avoid divide-by-zero
auto iterations = static_cast<double>(state.iterations()) *
static_cast<double>(state.iterations());
benchmark::DoNotOptimize(iterations);
}
namespace bm = benchmark;
state.counters["foo"] = bm::Counter{0.0001, bm::Counter::kInvert};
state.counters["bar"] = bm::Counter{10000, bm::Counter::kInvert};
}
BENCHMARK(BM_Invert)->ThreadRange(1, 8);
ADD_CASES(
TC_ConsoleOut,
{{"^BM_Invert/threads:%int %console_report bar=%hrfloatu foo=%hrfloatk$"}});
ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Invert/threads:%int\",$"},
{"\"family_index\": 3,$", MR_Next},
{"\"per_family_instance_index\": 0,$", MR_Next},
{"\"run_name\": \"BM_Invert/threads:%int\",$", MR_Next},
{"\"run_type\": \"iteration\",$", MR_Next},
{"\"repetitions\": 1,$", MR_Next},
{"\"repetition_index\": 0,$", MR_Next},
{"\"threads\": %int,$", MR_Next},
{"\"iterations\": %int,$", MR_Next},
{"\"real_time\": %float,$", MR_Next},
{"\"cpu_time\": %float,$", MR_Next},
{"\"time_unit\": \"ns\",$", MR_Next},
{"\"bar\": %float,$", MR_Next},
{"\"foo\": %float$", MR_Next},
{"}", MR_Next}});
ADD_CASES(TC_CSVOut,
{{"^\"BM_Invert/threads:%int\",%csv_report,%float,%float$"}});
// VS2013 does not allow this function to be passed as a lambda argument
// to CHECK_BENCHMARK_RESULTS()
void CheckInvert(Results const& e) {
CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. / (0.0001 * e.NumThreads()),
0.0001);
CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 1. / (10000 * e.NumThreads()),
0.0001);
}
CHECK_BENCHMARK_RESULTS("BM_Invert/threads:%int", &CheckInvert);
} // end namespace
// ========================================================================= //
// --------------------- InvertedRate Counters Output ---------------------- //
// ========================================================================= //
namespace {
void BM_Counters_InvertedRate(benchmark::State& state) {
for (auto _ : state) {
// This test requires a non-zero CPU time to avoid divide-by-zero
auto iterations = static_cast<double>(state.iterations()) *
static_cast<double>(state.iterations());
benchmark::DoNotOptimize(iterations);
}
namespace bm = benchmark;
state.counters["foo"] =
bm::Counter{1, bm::Counter::kIsRate | bm::Counter::kInvert};
state.counters["bar"] =
bm::Counter{8192, bm::Counter::kIsRate | bm::Counter::kInvert};
}
BENCHMARK(BM_Counters_InvertedRate)->ThreadRange(1, 8);
ADD_CASES(TC_ConsoleOut,
{{"^BM_Counters_InvertedRate/threads:%int %console_report "
"bar=%hrfloats foo=%hrfloats$"}});
ADD_CASES(TC_JSONOut,
{{"\"name\": \"BM_Counters_InvertedRate/threads:%int\",$"},
{"\"family_index\": 4,$", MR_Next},
{"\"per_family_instance_index\": 0,$", MR_Next},
{"\"run_name\": \"BM_Counters_InvertedRate/threads:%int\",$",
MR_Next},
{"\"run_type\": \"iteration\",$", MR_Next},
{"\"repetitions\": 1,$", MR_Next},
{"\"repetition_index\": 0,$", MR_Next},
{"\"threads\": %int,$", MR_Next},
{"\"iterations\": %int,$", MR_Next},
{"\"real_time\": %float,$", MR_Next},
{"\"cpu_time\": %float,$", MR_Next},
{"\"time_unit\": \"ns\",$", MR_Next},
{"\"bar\": %float,$", MR_Next},
{"\"foo\": %float$", MR_Next},
{"}", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_InvertedRate/"
"threads:%int\",%csv_report,%float,%float$"}});
// VS2013 does not allow this function to be passed as a lambda argument
// to CHECK_BENCHMARK_RESULTS()
void CheckInvertedRate(Results const& e) {
// this (and not real time) is the time used
double t = e.DurationCPUTime() / e.NumThreads();
// check that the values are within 0.1% of the expected values
CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, t / (e.NumThreads()), 0.001);
CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, t / (8192.0 * e.NumThreads()), 0.001);
}
CHECK_BENCHMARK_RESULTS("BM_Counters_InvertedRate/threads:%int",
&CheckInvertedRate);
} // end namespace
// ========================================================================= //
// ------------------------- Thread Counters Output ------------------------ //
// ========================================================================= //
namespace {
void BM_Counters_Threads(benchmark::State& state) {
for (auto _ : state) {
}
state.counters["foo"] = 1;
state.counters["bar"] = 2;
}
BENCHMARK(BM_Counters_Threads)->ThreadRange(1, 8);
ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_Threads/threads:%int %console_report "
"bar=%hrfloat foo=%hrfloat$"}});
ADD_CASES(TC_JSONOut,
{{"\"name\": \"BM_Counters_Threads/threads:%int\",$"},
{"\"family_index\": 5,$", MR_Next},
{"\"per_family_instance_index\": 0,$", MR_Next},
{"\"run_name\": \"BM_Counters_Threads/threads:%int\",$", MR_Next},
{"\"run_type\": \"iteration\",$", MR_Next},
{"\"repetitions\": 1,$", MR_Next},
{"\"repetition_index\": 0,$", MR_Next},
{"\"threads\": %int,$", MR_Next},
{"\"iterations\": %int,$", MR_Next},
{"\"real_time\": %float,$", MR_Next},
{"\"cpu_time\": %float,$", MR_Next},
{"\"time_unit\": \"ns\",$", MR_Next},
{"\"bar\": %float,$", MR_Next},
{"\"foo\": %float$", MR_Next},
{"}", MR_Next}});
ADD_CASES(
TC_CSVOut,
{{"^\"BM_Counters_Threads/threads:%int\",%csv_report,%float,%float$"}});
// VS2013 does not allow this function to be passed as a lambda argument
// to CHECK_BENCHMARK_RESULTS()
void CheckThreads(Results const& e) {
CHECK_COUNTER_VALUE(e, int, "foo", EQ, e.NumThreads());
CHECK_COUNTER_VALUE(e, int, "bar", EQ, 2 * e.NumThreads());
}
CHECK_BENCHMARK_RESULTS("BM_Counters_Threads/threads:%int", &CheckThreads);
} // end namespace
// ========================================================================= //
// ---------------------- ThreadAvg Counters Output ------------------------ //
// ========================================================================= //
namespace {
void BM_Counters_AvgThreads(benchmark::State& state) {
for (auto _ : state) {
}
namespace bm = benchmark;
state.counters["foo"] = bm::Counter{1, bm::Counter::kAvgThreads};
state.counters["bar"] = bm::Counter{2, bm::Counter::kAvgThreads};
}
BENCHMARK(BM_Counters_AvgThreads)->ThreadRange(1, 8);
ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_AvgThreads/threads:%int "
"%console_report bar=%hrfloat foo=%hrfloat$"}});
ADD_CASES(TC_JSONOut,
{{"\"name\": \"BM_Counters_AvgThreads/threads:%int\",$"},
{"\"family_index\": 6,$", MR_Next},
{"\"per_family_instance_index\": 0,$", MR_Next},
{"\"run_name\": \"BM_Counters_AvgThreads/threads:%int\",$", MR_Next},
{"\"run_type\": \"iteration\",$", MR_Next},
{"\"repetitions\": 1,$", MR_Next},
{"\"repetition_index\": 0,$", MR_Next},
{"\"threads\": %int,$", MR_Next},
{"\"iterations\": %int,$", MR_Next},
{"\"real_time\": %float,$", MR_Next},
{"\"cpu_time\": %float,$", MR_Next},
{"\"time_unit\": \"ns\",$", MR_Next},
{"\"bar\": %float,$", MR_Next},
{"\"foo\": %float$", MR_Next},
{"}", MR_Next}});
ADD_CASES(
TC_CSVOut,
{{"^\"BM_Counters_AvgThreads/threads:%int\",%csv_report,%float,%float$"}});
// VS2013 does not allow this function to be passed as a lambda argument
// to CHECK_BENCHMARK_RESULTS()
void CheckAvgThreads(Results const& e) {
CHECK_COUNTER_VALUE(e, int, "foo", EQ, 1);
CHECK_COUNTER_VALUE(e, int, "bar", EQ, 2);
}
CHECK_BENCHMARK_RESULTS("BM_Counters_AvgThreads/threads:%int",
&CheckAvgThreads);
} // end namespace
// ========================================================================= //
// ---------------------- ThreadAvg Counters Output ------------------------ //
// ========================================================================= //
namespace {
void BM_Counters_AvgThreadsRate(benchmark::State& state) {
for (auto _ : state) {
// This test requires a non-zero CPU time to avoid divide-by-zero
auto iterations = static_cast<double>(state.iterations()) *
static_cast<double>(state.iterations());
benchmark::DoNotOptimize(iterations);
}
namespace bm = benchmark;
state.counters["foo"] = bm::Counter{1, bm::Counter::kAvgThreadsRate};
state.counters["bar"] = bm::Counter{2, bm::Counter::kAvgThreadsRate};
}
BENCHMARK(BM_Counters_AvgThreadsRate)->ThreadRange(1, 8);
ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_AvgThreadsRate/threads:%int "
"%console_report bar=%hrfloat/s foo=%hrfloat/s$"}});
ADD_CASES(TC_JSONOut,
{{"\"name\": \"BM_Counters_AvgThreadsRate/threads:%int\",$"},
{"\"family_index\": 7,$", MR_Next},
{"\"per_family_instance_index\": 0,$", MR_Next},
{"\"run_name\": \"BM_Counters_AvgThreadsRate/threads:%int\",$",
MR_Next},
{"\"run_type\": \"iteration\",$", MR_Next},
{"\"repetitions\": 1,$", MR_Next},
{"\"repetition_index\": 0,$", MR_Next},
{"\"threads\": %int,$", MR_Next},
{"\"iterations\": %int,$", MR_Next},
{"\"real_time\": %float,$", MR_Next},
{"\"cpu_time\": %float,$", MR_Next},
{"\"time_unit\": \"ns\",$", MR_Next},
{"\"bar\": %float,$", MR_Next},
{"\"foo\": %float$", MR_Next},
{"}", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_AvgThreadsRate/"
"threads:%int\",%csv_report,%float,%float$"}});
// VS2013 does not allow this function to be passed as a lambda argument
// to CHECK_BENCHMARK_RESULTS()
void CheckAvgThreadsRate(Results const& e) {
// this (and not real time) is the time used
double t = e.DurationCPUTime() / e.NumThreads();
CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. / t, 0.001);
CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / t, 0.001);
}
CHECK_BENCHMARK_RESULTS("BM_Counters_AvgThreadsRate/threads:%int",
&CheckAvgThreadsRate);
} // end namespace
// ========================================================================= //
// ------------------- IterationInvariant Counters Output ------------------ //
// ========================================================================= //
namespace {
void BM_Counters_IterationInvariant(benchmark::State& state) {
for (auto _ : state) {
}
namespace bm = benchmark;
state.counters["foo"] = bm::Counter{1, bm::Counter::kIsIterationInvariant};
state.counters["bar"] = bm::Counter{2, bm::Counter::kIsIterationInvariant};
}
BENCHMARK(BM_Counters_IterationInvariant)->ThreadRange(1, 8);
ADD_CASES(TC_ConsoleOut,
{{"^BM_Counters_IterationInvariant/threads:%int %console_report "
"bar=%hrfloat foo=%hrfloat$"}});
ADD_CASES(TC_JSONOut,
{{"\"name\": \"BM_Counters_IterationInvariant/threads:%int\",$"},
{"\"family_index\": 8,$", MR_Next},
{"\"per_family_instance_index\": 0,$", MR_Next},
{"\"run_name\": \"BM_Counters_IterationInvariant/threads:%int\",$",
MR_Next},
{"\"run_type\": \"iteration\",$", MR_Next},
{"\"repetitions\": 1,$", MR_Next},
{"\"repetition_index\": 0,$", MR_Next},
{"\"threads\": %int,$", MR_Next},
{"\"iterations\": %int,$", MR_Next},
{"\"real_time\": %float,$", MR_Next},
{"\"cpu_time\": %float,$", MR_Next},
{"\"time_unit\": \"ns\",$", MR_Next},
{"\"bar\": %float,$", MR_Next},
{"\"foo\": %float$", MR_Next},
{"}", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_IterationInvariant/"
"threads:%int\",%csv_report,%float,%float$"}});
// VS2013 does not allow this function to be passed as a lambda argument
// to CHECK_BENCHMARK_RESULTS()
void CheckIterationInvariant(Results const& e) {
double its = e.NumIterations();
// check that the values are within 0.1% of the expected value
CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, its * e.NumThreads(), 0.001);
CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. * its * e.NumThreads(), 0.001);
}
CHECK_BENCHMARK_RESULTS("BM_Counters_IterationInvariant/threads:%int",
&CheckIterationInvariant);
} // end namespace
// ========================================================================= //
// ----------------- IterationInvariantRate Counters Output ---------------- //
// ========================================================================= //
namespace {
void BM_Counters_kIsIterationInvariantRate(benchmark::State& state) {
for (auto _ : state) {
// This test requires a non-zero CPU time to avoid divide-by-zero
auto iterations = static_cast<double>(state.iterations()) *
static_cast<double>(state.iterations());
benchmark::DoNotOptimize(iterations);
}
namespace bm = benchmark;
state.counters["foo"] =
bm::Counter{1, bm::Counter::kIsIterationInvariantRate};
state.counters["bar"] =
bm::Counter{2, bm::Counter::kIsRate | bm::Counter::kIsIterationInvariant};
}
BENCHMARK(BM_Counters_kIsIterationInvariantRate)->ThreadRange(1, 8);
ADD_CASES(TC_ConsoleOut,
{{"^BM_Counters_kIsIterationInvariantRate/threads:%int "
"%console_report bar=%hrfloat/s foo=%hrfloat/s$"}});
ADD_CASES(
TC_JSONOut,
{{"\"name\": \"BM_Counters_kIsIterationInvariantRate/threads:%int\",$"},
{"\"family_index\": 9,$", MR_Next},
{"\"per_family_instance_index\": 0,$", MR_Next},
{"\"run_name\": \"BM_Counters_kIsIterationInvariantRate/threads:%int\",$",
MR_Next},
{"\"run_type\": \"iteration\",$", MR_Next},
{"\"repetitions\": 1,$", MR_Next},
{"\"repetition_index\": 0,$", MR_Next},
{"\"threads\": %int,$", MR_Next},
{"\"iterations\": %int,$", MR_Next},
{"\"real_time\": %float,$", MR_Next},
{"\"cpu_time\": %float,$", MR_Next},
{"\"time_unit\": \"ns\",$", MR_Next},
{"\"bar\": %float,$", MR_Next},
{"\"foo\": %float$", MR_Next},
{"}", MR_Next}});
ADD_CASES(
TC_CSVOut,
{{"^\"BM_Counters_kIsIterationInvariantRate/threads:%int\",%csv_report,"
"%float,%float$"}});
// VS2013 does not allow this function to be passed as a lambda argument
// to CHECK_BENCHMARK_RESULTS()
void CheckIsIterationInvariantRate(Results const& e) {
double its = e.NumIterations();
// this (and not real time) is the time used
double t = e.DurationCPUTime() / e.NumThreads();
// check that the values are within 0.1% of the expected values
CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, its * 1. * e.NumThreads() / t, 0.001);
CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, its * 2. * e.NumThreads() / t, 0.001);
}
CHECK_BENCHMARK_RESULTS("BM_Counters_kIsIterationInvariantRate/threads:%int",
&CheckIsIterationInvariantRate);
} // end namespace
// ========================================================================= //
// --------------------- AvgIterations Counters Output --------------------- //
// ========================================================================= //
namespace {
void BM_Counters_AvgIterations(benchmark::State& state) {
for (auto _ : state) {
}
namespace bm = benchmark;
state.counters["foo"] = bm::Counter{1, bm::Counter::kAvgIterations};
state.counters["bar"] = bm::Counter{2, bm::Counter::kAvgIterations};
}
BENCHMARK(BM_Counters_AvgIterations)->ThreadRange(1, 8);
ADD_CASES(TC_ConsoleOut,
{{"^BM_Counters_AvgIterations/threads:%int %console_report "
"bar=%hrfloat foo=%hrfloat$"}});
ADD_CASES(TC_JSONOut,
{{"\"name\": \"BM_Counters_AvgIterations/threads:%int\",$"},
{"\"family_index\": 10,$", MR_Next},
{"\"per_family_instance_index\": 0,$", MR_Next},
{"\"run_name\": \"BM_Counters_AvgIterations/threads:%int\",$",
MR_Next},
{"\"run_type\": \"iteration\",$", MR_Next},
{"\"repetitions\": 1,$", MR_Next},
{"\"repetition_index\": 0,$", MR_Next},
{"\"threads\": %int,$", MR_Next},
{"\"iterations\": %int,$", MR_Next},
{"\"real_time\": %float,$", MR_Next},
{"\"cpu_time\": %float,$", MR_Next},
{"\"time_unit\": \"ns\",$", MR_Next},
{"\"bar\": %float,$", MR_Next},
{"\"foo\": %float$", MR_Next},
{"}", MR_Next}});
ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_AvgIterations/"
"threads:%int\",%csv_report,%float,%float$"}});
// VS2013 does not allow this function to be passed as a lambda argument
// to CHECK_BENCHMARK_RESULTS()
void CheckAvgIterations(Results const& e) {
double its = e.NumIterations();
// check that the values are within 0.1% of the expected value
CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. * e.NumThreads() / its, 0.001);
CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. * e.NumThreads() / its, 0.001);
}
CHECK_BENCHMARK_RESULTS("BM_Counters_AvgIterations/threads:%int",
&CheckAvgIterations);
} // end namespace
// ========================================================================= //
// ------------------- AvgIterationsRate Counters Output ------------------- //
// ========================================================================= //
namespace {
void BM_Counters_kAvgIterationsRate(benchmark::State& state) {
for (auto _ : state) {
// This test requires a non-zero CPU time to avoid divide-by-zero
auto iterations = static_cast<double>(state.iterations()) *
static_cast<double>(state.iterations());
benchmark::DoNotOptimize(iterations);
}
namespace bm = benchmark;
state.counters["foo"] = bm::Counter{1, bm::Counter::kAvgIterationsRate};
state.counters["bar"] =
bm::Counter{2, bm::Counter::kIsRate | bm::Counter::kAvgIterations};
}
BENCHMARK(BM_Counters_kAvgIterationsRate)->ThreadRange(1, 8);
ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_kAvgIterationsRate/threads:%int "
"%console_report bar=%hrfloat/s foo=%hrfloat/s$"}});
ADD_CASES(TC_JSONOut,
{{"\"name\": \"BM_Counters_kAvgIterationsRate/threads:%int\",$"},
{"\"family_index\": 11,$", MR_Next},
{"\"per_family_instance_index\": 0,$", MR_Next},
{"\"run_name\": \"BM_Counters_kAvgIterationsRate/threads:%int\",$",
MR_Next},
{"\"run_type\": \"iteration\",$", MR_Next},
{"\"repetitions\": 1,$", MR_Next},
{"\"repetition_index\": 0,$", MR_Next},
{"\"threads\": %int,$", MR_Next},
{"\"iterations\": %int,$", MR_Next},
{"\"real_time\": %float,$", MR_Next},
{"\"cpu_time\": %float,$", MR_Next},
{"\"time_unit\": \"ns\",$", MR_Next},
{"\"bar\": %float,$", MR_Next},
{"\"foo\": %float$", MR_Next},
{"}", MR_Next}});
ADD_CASES(TC_CSVOut,
{{"^\"BM_Counters_kAvgIterationsRate/threads:%int\",%csv_report,"
"%float,%float$"}});
// VS2013 does not allow this function to be passed as a lambda argument
// to CHECK_BENCHMARK_RESULTS()
void CheckAvgIterationsRate(Results const& e) {
double its = e.NumIterations();
// this (and not real time) is the time used
double t = e.DurationCPUTime() / e.NumThreads();
// check that the values are within 0.1% of the expected values
CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. * e.NumThreads() / its / t, 0.001);
CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. * e.NumThreads() / its / t, 0.001);
}
CHECK_BENCHMARK_RESULTS("BM_Counters_kAvgIterationsRate/threads:%int",
&CheckAvgIterationsRate);
} // end namespace
// ========================================================================= //
// --------------------------- TEST CASES END ------------------------------ //
// ========================================================================= //
int main(int argc, char* argv[]) {
benchmark::MaybeReenterWithoutASLR(argc, argv);
RunOutputTests(argc, argv);
}

Some files were not shown because too many files have changed in this diff Show More