[bazel] Build libpfm as a dependency to allow collection of perf counters (#1408)

* Build libpfm as a dependency to allow collection of perf counters

This commit builds libpfm using rules_foreign_cc and lets the default
build of the benchmark library support perf counter collection without
needing additional work from users.

Tested with a custom target:

```
bazel run \
        --override_repository=com_github_google_benchmark=/home/raghu/benchmark \
        -c opt :test-bench -- "--benchmark_perf_counters=INSTRUCTIONS,CYCLES"
Using profile: local

<snip>

----------------------------------------------------------------------
Benchmark            Time             CPU   Iterations UserCounters...
----------------------------------------------------------------------
BM_Test      0.279 ns        0.279 ns   1000000000 CYCLES=1.00888 INSTRUCTIONS=2

```

Signed-off-by: Raghu Raja <raghu@enfabrica.net>

* Adding myself to the CONTRIBUTORS file per CLA guidance

Enfabrica has already signed a corporate CLA.

Signed-off-by: Raghu Raja <raghu@enfabrica.net>

Signed-off-by: Raghu Raja <raghu@enfabrica.net>
This commit is contained in:
Raghu Raja 2022-10-31 04:03:59 -07:00 committed by GitHub
parent 4eaa0c896d
commit 398a8ac2e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 79 additions and 7 deletions

View File

@ -50,6 +50,7 @@ Norman Heino <norman.heino@gmail.com>
Oleksandr Sochka <sasha.sochka@gmail.com>
Ori Livneh <ori.livneh@gmail.com>
Paul Redmond <paul.redmond@gmail.com>
Raghu Raja <raghu@enfabrica.net>
Radoslav Yovchev <radoslav.tm@gmail.com>
Rainer Orth <ro@cebitec.uni-bielefeld.de>
Roman Lebedev <lebedev.ri@gmail.com>

View File

@ -18,6 +18,14 @@ config_setting(
visibility = [":__subpackages__"],
)
config_setting(
name = "perfcounters",
define_values = {
"pfm": "1",
},
visibility = [":__subpackages__"],
)
cc_library(
name = "benchmark",
srcs = glob(
@ -41,7 +49,16 @@ cc_library(
# Using `defines` (i.e. not `local_defines`) means that no
# dependent rules need to bother about defining the macro.
linkstatic = True,
defines = ["BENCHMARK_STATIC_DEFINE"],
defines = [
"BENCHMARK_STATIC_DEFINE",
] + select({
":perfcounters": ["HAVE_LIBPFM"],
"//conditions:default": [],
}),
deps = select({
":perfcounters": ["@libpfm//:libpfm"],
"//conditions:default": [],
}),
)
cc_library(

View File

@ -74,6 +74,7 @@ Paul Redmond <paul.redmond@gmail.com>
Pierre Phaneuf <pphaneuf@google.com>
Radoslav Yovchev <radoslav.tm@gmail.com>
Rainer Orth <ro@cebitec.uni-bielefeld.de>
Raghu Raja <raghu@enfabrica.net>
Raul Marin <rmrodriguez@cartodb.com>
Ray Glover <ray.glover@uk.ibm.com>
Robert Guo <robert.guo@mongodb.com>

View File

@ -3,6 +3,27 @@ workspace(name = "com_github_google_benchmark")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
http_archive(
name = "bazel_skylib",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.2.1/bazel-skylib-1.2.1.tar.gz",
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.2.1/bazel-skylib-1.2.1.tar.gz",
],
sha256 = "f7be3474d42aae265405a592bb7da8e171919d74c16f082a5457840f06054728",
)
# https://github.com/bazelbuild/rules_foreign_cc/
http_archive(
name = "rules_foreign_cc",
sha256 = "bcd0c5f46a49b85b384906daae41d277b3dc0ff27c7c752cc51e43048a58ec83",
strip_prefix = "rules_foreign_cc-0.7.1",
url = "https://github.com/bazelbuild/rules_foreign_cc/archive/0.7.1.tar.gz",
)
load("@rules_foreign_cc//foreign_cc:repositories.bzl", "rules_foreign_cc_dependencies")
rules_foreign_cc_dependencies()
http_archive(
name = "com_google_absl",
sha256 = "f41868f7a938605c92936230081175d1eae87f6ea2c248f41077c8f88316f111",
@ -16,6 +37,16 @@ git_repository(
tag = "release-1.11.0",
)
# Downloaded from v4.9.0 tag at https://sourceforge.net/p/perfmon2/libpfm4/ref/master/tags/
http_archive(
name = "libpfm",
build_file = "//tools:libpfm.BUILD.bazel",
sha256 = "5da5f8872bde14b3634c9688d980f68bda28b510268723cc12973eedbab9fecc",
type = "tar.gz",
strip_prefix = "libpfm-4.11.0",
urls = ["https://sourceforge.net/projects/perfmon2/files/libpfm4/libpfm-4.11.0.tar.gz/download"],
)
http_archive(
name = "pybind11",
build_file = "@//bindings/python:pybind11.BUILD",

View File

@ -12,16 +12,17 @@ This feature is available if:
* The benchmark is run on an architecture featuring a Performance Monitoring
Unit (PMU),
* The benchmark is compiled with support for collecting counters. Currently,
this requires [libpfm](http://perfmon2.sourceforge.net/) be available at build
time
this requires [libpfm](http://perfmon2.sourceforge.net/), which is built as a
dependency via Bazel.
The feature does not require modifying benchmark code. Counter collection is
handled at the boundaries where timer collection is also handled.
To opt-in:
* Install `libpfm4-dev`, e.g. `apt-get install libpfm4-dev`.
* Enable the cmake flag BENCHMARK_ENABLE_LIBPFM.
* If using a Bazel build, add `--define pfm=1` to your buid flags
* If using CMake:
* Install `libpfm4-dev`, e.g. `apt-get install libpfm4-dev`.
* Enable the CMake flag `BENCHMARK_ENABLE_LIBPFM` in `CMakeLists.txt`.
To use, pass a comma-separated list of counter names through the
`--benchmark_perf_counters` flag. The names are decoded through libpfm - meaning,
@ -31,4 +32,4 @@ mapped by libpfm to platform-specifics - see libpfm
The counter values are reported back through the [User Counters](../README.md#custom-counters)
mechanism, meaning, they are available in all the formats (e.g. JSON) supported
by User Counters.
by User Counters.

21
tools/libpfm.BUILD.bazel Normal file
View File

@ -0,0 +1,21 @@
# Build rule for libpfm, which is required to collect performance counters for
# BENCHMARK_ENABLE_LIBPFM builds.
load("@rules_foreign_cc//foreign_cc:defs.bzl", "make")
filegroup(
name = "pfm_srcs",
srcs = glob(["**"]),
)
make(
name = "libpfm",
lib_source = ":pfm_srcs",
lib_name = "libpfm",
copts = [
"-Wno-format-truncation",
],
visibility = [
"//visibility:public",
],
)