mirror of
https://boringssl.googlesource.com/boringssl
synced 2026-07-21 14:43:51 +00:00
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:
committed by
Boringssl LUCI CQ
parent
e50923e3de
commit
2a5cd33a2a
@@ -1,2 +1,3 @@
|
||||
third_party/benchmark
|
||||
third_party/googletest
|
||||
util/bazel-example
|
||||
|
||||
+1
-1
@@ -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")
|
||||
|
||||
Generated
+2
-2
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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()) {
|
||||
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
8.2.1
|
||||
+11
@@ -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
@@ -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
@@ -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
@@ -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: |
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -66,3 +66,4 @@ CMakeSettings.json
|
||||
# Python build stuff
|
||||
dist/
|
||||
*.egg-info*
|
||||
uv.lock
|
||||
|
||||
+4
-4
@@ -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
|
||||
|
||||
Vendored
+4
@@ -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>
|
||||
|
||||
Vendored
+103
@@ -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__"],
|
||||
)
|
||||
Vendored
+17
-7
@@ -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()
|
||||
|
||||
Vendored
+4
@@ -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>
|
||||
|
||||
Vendored
+3
-3
@@ -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
|
||||
}
|
||||
|
||||
Vendored
+2
-2
@@ -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)
|
||||
|
||||
Vendored
+1
-1
@@ -2,9 +2,9 @@
|
||||
|
||||
[](https://github.com/google/benchmark/actions?query=workflow%3Abuild-and-test)
|
||||
[](https://github.com/google/benchmark/actions/workflows/bazel.yml)
|
||||
[](https://github.com/google/benchmark/actions?query=workflow%3Apylint)
|
||||
[](https://github.com/google/benchmark/actions?query=workflow%3Atest-bindings)
|
||||
[](https://coveralls.io/r/google/benchmark)
|
||||
[](https://securityscorecards.dev/viewer/?uri=github.com/google/benchmark)
|
||||
|
||||
[](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
@@ -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
@@ -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
@@ -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
@@ -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) {}
|
||||
|
||||
Vendored
+2
-3
@@ -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]
|
||||
|
||||
Vendored
+6
-1
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
//=============================================================================//
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "check.h"
|
||||
|
||||
+10
-4
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Vendored
+4
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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) {
|
||||
|
||||
Vendored
+2
@@ -15,6 +15,8 @@
|
||||
#ifndef BENCHMARK_RE_H_
|
||||
#define BENCHMARK_RE_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "internal_macros.h"
|
||||
|
||||
// clang-format off
|
||||
|
||||
+3
-2
@@ -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
|
||||
|
||||
Vendored
+1
-1
@@ -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)
|
||||
|
||||
Vendored
+135
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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 ----------------------------- //
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic ignored "-Wreturn-type"
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
#endif
|
||||
|
||||
// clang-format off
|
||||
|
||||
+1
-1
@@ -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 {}
|
||||
|
||||
@@ -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
@@ -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 ------------------------------ //
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user