benchmark icon indicating copy to clipboard operation
benchmark copied to clipboard

Build libpfm as a dependency to allow collection of perf counters

Open rajachan opened this issue 2 years ago • 10 comments

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

rajachan avatar Jun 08 '22 17:06 rajachan

it'll need to be added to cmake too. and do we actually want to push the cost of the extra library on to all end users, even if they don't care about perf counters?

dmah42 avatar Jun 09 '22 08:06 dmah42

it'll need to be added to cmake too. and do we actually want to push the cost of the extra library on to all end users, even if they don't care about perf counters?

Now that bazelisk builds it on behalf of users, it should be a self-contained target with no meaningful impact for those who do not care about the feature... unless you think there's a runtime cost associated with this path? As an alternative, I can add a separate target with libpfm support, giving folks an option to use either one. Thoughts?

rajachan avatar Jun 16 '22 00:06 rajachan

Fixed build failures.

rajachan avatar Jun 16 '22 06:06 rajachan

bazel failures look reasonably like this PR caused them.

dmah42 avatar Jun 17 '22 16:06 dmah42

//test:perf_counters_gtest and //test:perf_counters_test are failing. Are these tests that never ran before in the CI environment, given the perf counter path was not built?

[  FAILED  ] PerfCountersTest.ReopenExistingCounters (0 ms)
[ RUN      ] PerfCountersTest.CreateExistingMeasurements
test/perf_counters_gtest.cc:139: Failure
Value of: perf_counter_measurements[8].Stop(measurements)
  Actual: true
Expected: false
test/perf_counters_gtest.cc:143: Failure
Value of: perf_counter_measurements[9].Stop(measurements)
  Actual: true
Expected: false
[  FAILED  ] PerfCountersTest.CreateExistingMeasurements (0 ms)

rajachan avatar Jun 20 '22 06:06 rajachan

yes, it's possible. but it suggests that the bazel config is not quite the same as the cmake one.

dmah42 avatar Jun 20 '22 09:06 dmah42

Perhaps I am not following your ask. CMake uses check_library_exists to build with the perf counter support when the library is available on the system benchmark is getting built on. Unlike Bazel, CMake doesn't let us vendor a library in a hermetic way. I did notice BENCHMARK_ENABLE_LIBPFM was set to OFF, forcefully disabling the counters. Turning that back on still doesn't let the test pass as I expected. It also doesn't look like the tests are using the CMake build? To clarify, I am using the same define, HAVE_LIBPFM, that CMake uses here:

# libpfm, if available                                                          
if (HAVE_LIBPFM)                                                                
  target_link_libraries(benchmark PRIVATE pfm)                                  
  add_definitions(-DHAVE_LIBPFM)                                                
endif()  

rajachan avatar Jun 20 '22 17:06 rajachan

Perhaps I am not following your ask. CMake uses check_library_exists to build with the perf counter support when the library is available on the system benchmark is getting built on. Unlike Bazel, CMake doesn't let us vendor a library in a hermetic way. I did notice BENCHMARK_ENABLE_LIBPFM was set to OFF, forcefully disabling the counters. Turning that back on still doesn't let the test pass as I expected. It also doesn't look like the tests are using the CMake build?

yes, there are perf counter tests that use cmake (build-and-test-perfcounters). with your change, we are now also running these same tests on the bazel build for the first time, but they're failing. which suggests something about how the bazel build is configured is different from the cmake build-and-test-perfcounters build.

my initial guess would be: the cmake version doesn't run the tests as they fail due to permissions issues.

so to be equivalent, you may need to just filter out the pfm tests from the bazel workflow on the CI bots.

To clarify, I am using the same define, HAVE_LIBPFM, that CMake uses here:

# libpfm, if available                                                          
if (HAVE_LIBPFM)                                                                
  target_link_libraries(benchmark PRIVATE pfm)                                  
  add_definitions(-DHAVE_LIBPFM)                                                
endif()  

dmah42 avatar Jun 21 '22 08:06 dmah42

Apologies for letting this sit, I've been taking some time off. I hope to get back to this next week.

rajachan avatar Jul 27 '22 16:07 rajachan

If this is bazel-specific, it should not touch non-bazel stuff.

LebedevRI avatar Jul 27 '22 16:07 LebedevRI

Addressed the CMake situation, removed the explicit CMakeLists.txt change to always turn on PFM... Added a config_setting to make this optional for Bazel builds too. Please take a look @LebedevRI

rajachan avatar Oct 27 '22 20:10 rajachan

As long as it's bazel-only i have no comments :)

LebedevRI avatar Oct 27 '22 20:10 LebedevRI

thanks for coming back to it. i just had one comment :)

dmah42 avatar Oct 28 '22 10:10 dmah42