Skip to content

Commit

Permalink
[bazel] Build libpfm as a dependency to allow collection of perf coun…
Browse files Browse the repository at this point in the history
…ters (#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 <[email protected]>

* Adding myself to the CONTRIBUTORS file per CLA guidance

Enfabrica has already signed a corporate CLA.

Signed-off-by: Raghu Raja <[email protected]>

Signed-off-by: Raghu Raja <[email protected]>
  • Loading branch information
rajachan authored Oct 31, 2022
1 parent 4eaa0c8 commit 398a8ac
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 7 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Norman Heino <[email protected]>
Oleksandr Sochka <[email protected]>
Ori Livneh <[email protected]>
Paul Redmond <[email protected]>
Raghu Raja <[email protected]>
Radoslav Yovchev <[email protected]>
Rainer Orth <[email protected]>
Roman Lebedev <[email protected]>
Expand Down
19 changes: 18 additions & 1 deletion BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ config_setting(
visibility = [":__subpackages__"],
)

config_setting(
name = "perfcounters",
define_values = {
"pfm": "1",
},
visibility = [":__subpackages__"],
)

cc_library(
name = "benchmark",
srcs = glob(
Expand All @@ -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(
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTORS
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ Paul Redmond <[email protected]>
Pierre Phaneuf <[email protected]>
Radoslav Yovchev <[email protected]>
Rainer Orth <[email protected]>
Raghu Raja <[email protected]>
Raul Marin <[email protected]>
Ray Glover <[email protected]>
Robert Guo <[email protected]>
Expand Down
31 changes: 31 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
13 changes: 7 additions & 6 deletions docs/perf_counters.md
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 changes: 21 additions & 0 deletions tools/libpfm.BUILD.bazel
Original file line number Diff line number Diff line change
@@ -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",
],
)

0 comments on commit 398a8ac

Please sign in to comment.