Skip to content

Commit

Permalink
Add benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
mingxwa committed Oct 2, 2024
1 parent a029db0 commit 5de03cf
Show file tree
Hide file tree
Showing 10 changed files with 198 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
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
./build-clang-16/benchmarks/msft_proxy_benchmarks
./build-clang-17/benchmarks/msft_proxy_benchmarks
./build-clang-18/benchmarks/msft_proxy_benchmarks
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
./build-gcc-12/benchmarks/msft_proxy_benchmarks
./build-gcc-13/benchmarks/msft_proxy_benchmarks
./build-gcc-14/benchmarks/msft_proxy_benchmarks
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
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()
30 changes: 30 additions & 0 deletions benchmarks/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
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_small_object_invocation_benchmark_context.cpp
proxy_small_object_invocation_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()
27 changes: 27 additions & 0 deletions benchmarks/proxy_small_object_invocation_benchmark.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#include <benchmark/benchmark.h>

#include "proxy_small_object_invocation_benchmark_context.h"

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

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

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

#include "proxy_small_object_invocation_benchmark_context.h"

namespace {

constexpr std::size_t TestDataSize = 1500000;
constexpr std::size_t TypeSeriesCount = 3;

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

private:
int seed_;
};

template <std::size_t TypeSeries>
class IntrusiveImpl : public TestBase {
public:
explicit IntrusiveImpl(int seed) noexcept : seed_(seed) {}
IntrusiveImpl(const IntrusiveImpl&) noexcept = default;
int Fun() const noexcept override { return seed_ ^ (TypeSeries + 1u); }

private:
int seed_;
};

template <std::size_t FromTypeSeries>
void FillProxyTestData(std::vector<pro::proxy<TestFacade>>& data) {
if constexpr (FromTypeSeries < TypeSeriesCount) {
for (std::size_t i = FromTypeSeries; i < data.size(); i += TypeSeriesCount) {
data[i] = pro::make_proxy<TestFacade, NonIntrusiveImpl<FromTypeSeries>>(static_cast<int>(i));
}
FillProxyTestData<FromTypeSeries + 1u>(data);
}
}

std::vector<pro::proxy<TestFacade>> GenerateProxyTestData() {
std::vector<pro::proxy<TestFacade>> result(TestDataSize);
FillProxyTestData<0u>(result);
return result;
}

template <std::size_t FromTypeSeries>
void FillVirtualFunctionTestData(std::vector<std::unique_ptr<TestBase>>& data) {
if constexpr (FromTypeSeries < TypeSeriesCount) {
for (std::size_t i = FromTypeSeries; i < data.size(); i += TypeSeriesCount) {
data[i].reset(new IntrusiveImpl<FromTypeSeries>(static_cast<int>(i)));
}
FillVirtualFunctionTestData<FromTypeSeries + 1u>(data);
}
}

std::vector<std::unique_ptr<TestBase>> GenerateVirtualFunctionTestData() {
std::vector<std::unique_ptr<TestBase>> result(TestDataSize);
FillVirtualFunctionTestData<0u>(result);
return result;
}

} // namespace

const std::vector<pro::proxy<TestFacade>> ProxyTestData = GenerateProxyTestData();
const std::vector<std::unique_ptr<TestBase>> VirtualFunctionTestData = GenerateVirtualFunctionTestData();
21 changes: 21 additions & 0 deletions benchmarks/proxy_small_object_invocation_benchmark_context.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#include <memory>
#include <vector>

#include "proxy.h"

PRO_DEF_MEM_DISPATCH(MemFun, Fun);

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

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

extern const std::vector<pro::proxy<TestFacade>> ProxyTestData;
extern const std::vector<std::unique_ptr<TestBase>> VirtualFunctionTestData;
21 changes: 19 additions & 2 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,21 @@
project(msft_proxy_tests)

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
URL_HASH SHA256=7b42b4d6ed48810c5362c265a17faebe90dc2373c885e5216439d37927f02926
)
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_executable(msft_proxy_tests
proxy_creation_tests.cpp
proxy_dispatch_tests.cpp
Expand All @@ -13,9 +30,9 @@ target_link_libraries(msft_proxy_tests PRIVATE msft_proxy)
target_link_libraries(msft_proxy_tests PRIVATE gtest_main)

if (MSVC)
target_compile_options(msft_proxy_tests PRIVATE /W4 /WX)
target_compile_options(msft_proxy_tests PRIVATE /W4)
else()
target_compile_options(msft_proxy_tests PRIVATE -Wall -Wextra -Wpedantic -Werror)
target_compile_options(msft_proxy_tests PRIVATE -Wall -Wextra -Wpedantic)
endif()

include(GoogleTest)
Expand Down

0 comments on commit 5de03cf

Please sign in to comment.