Skip to content

Commit

Permalink
Add benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
mingxwa committed Oct 4, 2024
1 parent a029db0 commit 767a58e
Show file tree
Hide file tree
Showing 11 changed files with 339 additions and 30 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/bvt-appleclang.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ jobs:
- name: build and run test with AppleClang
run: |
cmake -B build
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
ctest --test-dir build -j
- name: run benchmarks
run: |
./build/benchmarks/msft_proxy_benchmarks --benchmark_repetitions=10 --benchmark_report_aggregates_only=true
15 changes: 11 additions & 4 deletions .github/workflows/bvt-clang.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,31 @@ jobs:
- name: build and run test with clang 15
run: |
cmake -B build-clang-15 -DCMAKE_C_COMPILER=clang-15 -DCMAKE_CXX_COMPILER=clang++-15
cmake -B build-clang-15 -DCMAKE_C_COMPILER=clang-15 -DCMAKE_CXX_COMPILER=clang++-15 -DCMAKE_BUILD_TYPE=Release
cmake --build build-clang-15 -j
ctest --test-dir build-clang-15 -j
- name: build and run test with clang 16
run: |
cmake -B build-clang-16 -DCMAKE_C_COMPILER=clang-16 -DCMAKE_CXX_COMPILER=clang++-16
cmake -B build-clang-16 -DCMAKE_C_COMPILER=clang-16 -DCMAKE_CXX_COMPILER=clang++-16 -DCMAKE_BUILD_TYPE=Release
cmake --build build-clang-16 -j
ctest --test-dir build-clang-16 -j
- name: build and run test with clang 17
run: |
cmake -B build-clang-17 -DCMAKE_C_COMPILER=clang-17 -DCMAKE_CXX_COMPILER=clang++-17
cmake -B build-clang-17 -DCMAKE_C_COMPILER=clang-17 -DCMAKE_CXX_COMPILER=clang++-17 -DCMAKE_BUILD_TYPE=Release
cmake --build build-clang-17 -j
ctest --test-dir build-clang-17 -j
- name: build and run test with clang 18
run: |
cmake -B build-clang-18 -DCMAKE_C_COMPILER=clang-18 -DCMAKE_CXX_COMPILER=clang++-18
cmake -B build-clang-18 -DCMAKE_C_COMPILER=clang-18 -DCMAKE_CXX_COMPILER=clang++-18 -DCMAKE_BUILD_TYPE=Release
cmake --build build-clang-18 -j
ctest --test-dir build-clang-18 -j
- name: run benchmarks
run: |
./build-clang-15/benchmarks/msft_proxy_benchmarks --benchmark_repetitions=10 --benchmark_report_aggregates_only=true
./build-clang-16/benchmarks/msft_proxy_benchmarks --benchmark_repetitions=10 --benchmark_report_aggregates_only=true
./build-clang-17/benchmarks/msft_proxy_benchmarks --benchmark_repetitions=10 --benchmark_report_aggregates_only=true
./build-clang-18/benchmarks/msft_proxy_benchmarks --benchmark_repetitions=10 --benchmark_report_aggregates_only=true
15 changes: 11 additions & 4 deletions .github/workflows/bvt-gcc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,31 @@ jobs:
- name: build and run test with gcc 11
run: |
cmake -B build-gcc-11 -DCMAKE_C_COMPILER=gcc-11 -DCMAKE_CXX_COMPILER=g++-11
cmake -B build-gcc-11 -DCMAKE_C_COMPILER=gcc-11 -DCMAKE_CXX_COMPILER=g++-11 -DCMAKE_BUILD_TYPE=Release
cmake --build build-gcc-11 -j
ctest --test-dir build-gcc-11 -j
- name: build and run test with gcc 12
run: |
cmake -B build-gcc-12 -DCMAKE_C_COMPILER=gcc-12 -DCMAKE_CXX_COMPILER=g++-12
cmake -B build-gcc-12 -DCMAKE_C_COMPILER=gcc-12 -DCMAKE_CXX_COMPILER=g++-12 -DCMAKE_BUILD_TYPE=Release
cmake --build build-gcc-12 -j
ctest --test-dir build-gcc-12 -j
- name: build and run test with gcc 13
run: |
cmake -B build-gcc-13 -DCMAKE_C_COMPILER=gcc-13 -DCMAKE_CXX_COMPILER=g++-13
cmake -B build-gcc-13 -DCMAKE_C_COMPILER=gcc-13 -DCMAKE_CXX_COMPILER=g++-13 -DCMAKE_BUILD_TYPE=Release
cmake --build build-gcc-13 -j
ctest --test-dir build-gcc-13 -j
- name: build and run test with gcc 14
run: |
cmake -B build-gcc-14 -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14
cmake -B build-gcc-14 -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14 -DCMAKE_BUILD_TYPE=Release
cmake --build build-gcc-14 -j
ctest --test-dir build-gcc-14 -j
- name: run benchmarks
run: |
./build-gcc-11/benchmarks/msft_proxy_benchmarks --benchmark_repetitions=10 --benchmark_report_aggregates_only=true
./build-gcc-12/benchmarks/msft_proxy_benchmarks --benchmark_repetitions=10 --benchmark_report_aggregates_only=true
./build-gcc-13/benchmarks/msft_proxy_benchmarks --benchmark_repetitions=10 --benchmark_report_aggregates_only=true
./build-gcc-14/benchmarks/msft_proxy_benchmarks --benchmark_repetitions=10 --benchmark_report_aggregates_only=true
9 changes: 5 additions & 4 deletions .github/workflows/bvt-msvc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ jobs:
with:
ref: ${{ inputs.branch }}

- name: build with cmake
- name: build and run test with MSVC
run: |
cmake -B build
cmake --build build -j
cmake --build build --config Release -j
ctest --test-dir build -j
- name: run tests
- name: run benchmarks
run: |
ctest --test-dir build -j
.\build\benchmarks\Release\msft_proxy_benchmarks.exe --benchmark_repetitions=10 --benchmark_report_aggregates_only=true
16 changes: 1 addition & 15 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,7 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/proxyConfigVersion.cmake
# build tests if BUILD_TESTING is ON
include(CTest)
if (BUILD_TESTING)
include(FetchContent)
# The policy uses the download time for timestamp, instead of the timestamp in the archive. This
# allows for proper rebuilds when a projects URL changes.
if(POLICY CMP0135)
cmake_policy(SET CMP0135 NEW)
endif()
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/releases/download/v1.15.2/googletest-1.15.2.tar.gz
)

set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) # For Windows: Prevent overriding the parent project's compiler/linker settings
set(BUILD_GMOCK OFF CACHE BOOL "" FORCE) # Disable GMock
FetchContent_MakeAvailable(googletest)

add_subdirectory(tests)
add_subdirectory(benchmarks)
add_subdirectory(samples)
endif()
31 changes: 31 additions & 0 deletions benchmarks/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
project(msft_proxy_benchmarks)

include(FetchContent)
# The policy uses the download time for timestamp, instead of the timestamp in the archive. This
# allows for proper rebuilds when a projects URL changes.
if(POLICY CMP0135)
cmake_policy(SET CMP0135 NEW)
endif()

FetchContent_Declare(
benchmark
URL https://github.com/google/benchmark/archive/refs/tags/v1.9.0.tar.gz
URL_HASH SHA256=35a77f46cc782b16fac8d3b107fbfbb37dcd645f7c28eee19f3b8e0758b48994
)
set(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL "Disable tests for google benchmark")
set(BENCHMARK_ENABLE_GTEST_TESTS OFF CACHE BOOL "Disable google benchmark unit tests")
FetchContent_MakeAvailable(benchmark)

add_executable(msft_proxy_benchmarks
proxy_invocation_benchmark_context.cpp
proxy_invocation_benchmark.cpp
proxy_management_benchmark.cpp
)
target_include_directories(msft_proxy_benchmarks PRIVATE .)
target_link_libraries(msft_proxy_benchmarks PRIVATE msft_proxy benchmark::benchmark benchmark::benchmark_main)

if (MSVC)
target_compile_options(msft_proxy_benchmarks PRIVATE /W4)
else()
target_compile_options(msft_proxy_benchmarks PRIVATE -Wall -Wextra -Wpedantic)
endif()
47 changes: 47 additions & 0 deletions benchmarks/proxy_invocation_benchmark.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#include <benchmark/benchmark.h>

#include "proxy_invocation_benchmark_context.h"

void BM_SmallObjectInvocationViaProxy(benchmark::State& state) {
for (auto _ : state) {
for (auto& p : SmallObjectInvocationProxyTestData) {
int result = p->Fun();
benchmark::DoNotOptimize(result);
}
}
}

void BM_SmallObjectInvocationViaVirtualFunction(benchmark::State& state) {
for (auto _ : state) {
for (auto& p : SmallObjectInvocationVirtualFunctionTestData) {
int result = p->Fun();
benchmark::DoNotOptimize(result);
}
}
}

void BM_LargeObjectInvocationViaProxy(benchmark::State& state) {
for (auto _ : state) {
for (auto& p : LargeObjectInvocationProxyTestData) {
int result = p->Fun();
benchmark::DoNotOptimize(result);
}
}
}

void BM_LargeObjectInvocationViaVirtualFunction(benchmark::State& state) {
for (auto _ : state) {
for (auto& p : LargeObjectInvocationVirtualFunctionTestData) {
int result = p->Fun();
benchmark::DoNotOptimize(result);
}
}
}

BENCHMARK(BM_SmallObjectInvocationViaProxy);
BENCHMARK(BM_SmallObjectInvocationViaVirtualFunction);
BENCHMARK(BM_LargeObjectInvocationViaProxy);
BENCHMARK(BM_LargeObjectInvocationViaVirtualFunction);
96 changes: 96 additions & 0 deletions benchmarks/proxy_invocation_benchmark_context.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#include "proxy_invocation_benchmark_context.h"

namespace {

constexpr int TestDataSize = 1000000;
constexpr int TypeSeriesCount = 100;

template <int TypeSeries>
class NonIntrusiveSmallImpl {
public:
explicit NonIntrusiveSmallImpl(int seed) noexcept : seed_(seed) {}
NonIntrusiveSmallImpl(const NonIntrusiveSmallImpl&) noexcept = default;
int Fun() const noexcept { return seed_ ^ (TypeSeries + 1); }

private:
int seed_;
};

template <int TypeSeries>
class NonIntrusiveLargeImpl {
public:
explicit NonIntrusiveLargeImpl(int seed) noexcept : seed_(seed) {}
NonIntrusiveLargeImpl(const NonIntrusiveLargeImpl&) noexcept = default;
int Fun() const noexcept { return seed_ ^ (TypeSeries + 1); }

private:
void* padding_[16]{};
int seed_;
};

template <int TypeSeries>
class IntrusiveSmallImpl : public InvocationTestBase {
public:
explicit IntrusiveSmallImpl(int seed) noexcept : seed_(seed) {}
IntrusiveSmallImpl(const IntrusiveSmallImpl&) noexcept = default;
int Fun() const noexcept override { return seed_ ^ (TypeSeries + 1); }

private:
int seed_;
};

template <int TypeSeries>
class IntrusiveLargeImpl : public InvocationTestBase {
public:
explicit IntrusiveLargeImpl(int seed) noexcept : seed_(seed) {}
IntrusiveLargeImpl(const IntrusiveLargeImpl&) noexcept = default;
int Fun() const noexcept override { return seed_ ^ (TypeSeries + 1); }

private:
void* padding_[16]{};
int seed_;
};

template <template <int> class T, int FromTypeSeries>
void FillProxyTestData(std::vector<pro::proxy<InvocationTestFacade>>& data) {
if constexpr (FromTypeSeries < TypeSeriesCount) {
for (int i = FromTypeSeries; i < TestDataSize; i += TypeSeriesCount) {
data[i] = pro::make_proxy<InvocationTestFacade, T<FromTypeSeries>>(static_cast<int>(i));
}
FillProxyTestData<T, FromTypeSeries + 1>(data);
}
}

template <template <int> class T>
std::vector<pro::proxy<InvocationTestFacade>> GenerateProxyTestData() {
std::vector<pro::proxy<InvocationTestFacade>> result(TestDataSize);
FillProxyTestData<T, 0>(result);
return result;
}

template <template <int> class T, int FromTypeSeries>
void FillVirtualFunctionTestData(std::vector<std::unique_ptr<InvocationTestBase>>& data) {
if constexpr (FromTypeSeries < TypeSeriesCount) {
for (int i = FromTypeSeries; i < TestDataSize; i += TypeSeriesCount) {
data[i].reset(new T<FromTypeSeries>(static_cast<int>(i)));
}
FillVirtualFunctionTestData<T, FromTypeSeries + 1>(data);
}
}

template <template <int> class T>
std::vector<std::unique_ptr<InvocationTestBase>> GenerateVirtualFunctionTestData() {
std::vector<std::unique_ptr<InvocationTestBase>> result(TestDataSize);
FillVirtualFunctionTestData<T, 0>(result);
return result;
}

} // namespace

const std::vector<pro::proxy<InvocationTestFacade>> SmallObjectInvocationProxyTestData = GenerateProxyTestData<NonIntrusiveSmallImpl>();
const std::vector<std::unique_ptr<InvocationTestBase>> SmallObjectInvocationVirtualFunctionTestData = GenerateVirtualFunctionTestData<IntrusiveSmallImpl>();
const std::vector<pro::proxy<InvocationTestFacade>> LargeObjectInvocationProxyTestData = GenerateProxyTestData<NonIntrusiveLargeImpl>();
const std::vector<std::unique_ptr<InvocationTestBase>> LargeObjectInvocationVirtualFunctionTestData = GenerateVirtualFunctionTestData<IntrusiveLargeImpl>();
23 changes: 23 additions & 0 deletions benchmarks/proxy_invocation_benchmark_context.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#include <memory>
#include <vector>

#include "proxy.h"

PRO_DEF_MEM_DISPATCH(MemFun, Fun);

struct InvocationTestFacade : pro::facade_builder
::add_convention<MemFun, int() const>
::build{};

struct InvocationTestBase {
virtual int Fun() const = 0;
virtual ~InvocationTestBase() = default;
};

extern const std::vector<pro::proxy<InvocationTestFacade>> SmallObjectInvocationProxyTestData;
extern const std::vector<std::unique_ptr<InvocationTestBase>> SmallObjectInvocationVirtualFunctionTestData;
extern const std::vector<pro::proxy<InvocationTestFacade>> LargeObjectInvocationProxyTestData;
extern const std::vector<std::unique_ptr<InvocationTestBase>> LargeObjectInvocationVirtualFunctionTestData;
Loading

0 comments on commit 767a58e

Please sign in to comment.