Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ compile_commands.json
CTestTestfile.cmake
_deps
CMakeUserPresets.json
out/

# CLion
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
Expand Down
52 changes: 45 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,20 @@ FetchContent_Declare(
FIND_PACKAGE_ARGS NAMES benchmark CONFIG
)
set(BENCHMARK_ENABLE_TESTING OFF)
set(BENCHMARK_ENABLE_WERROR OFF CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googlebenchmark)

if(TARGET benchmark)
target_compile_options(benchmark PRIVATE
$<$<CXX_COMPILER_ID:Clang>:-Wno-c2y-extensions -Wno-invalid-offsetof>
)
endif()
if(TARGET benchmark_main)
target_compile_options(benchmark_main PRIVATE
$<$<CXX_COMPILER_ID:Clang>:-Wno-c2y-extensions -Wno-invalid-offsetof>
)
endif()

# Google Test
enable_testing()
FetchContent_Declare(
Expand All @@ -39,8 +51,19 @@ set(HDR_HISTOGRAM_BUILD_SHARED OFF CACHE BOOL "" FORCE)
set(HDR_LOG_REQUIRED "DISABLED" CACHE STRING "" FORCE)
FetchContent_MakeAvailable(hdrhistogram)

# moodycamel ConcurrentQueue
FetchContent_Declare(
concurrentqueue
URL https://github.com/cameron314/concurrentqueue/archive/refs/tags/v1.0.5.zip
)
FetchContent_MakeAvailable(concurrentqueue)

find_package(Threads REQUIRED)

set(ATOMIC_LIBRARY
$<$<AND:$<NOT:$<CXX_COMPILER_ID:MSVC>>,$<NOT:$<PLATFORM_ID:Windows>>>:atomic>
)

set(COMMON_TARGET_PROPERTIES
PRIVATE
${DEFAULT_RELEASE_OPTS}
Expand All @@ -58,7 +81,7 @@ target_link_libraries(mpsc_bench_throughput
PRIVATE
benchmark::benchmark_main
Threads::Threads
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:atomic>
${ATOMIC_LIBRARY}
)
target_compile_options(mpsc_bench_throughput ${COMMON_TARGET_PROPERTIES})

Expand All @@ -74,7 +97,7 @@ target_link_libraries(mpsc_bench_latency
benchmark::benchmark_main
hdr_histogram_static
Threads::Threads
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:atomic>
${ATOMIC_LIBRARY}
)
target_compile_options(mpsc_bench_latency ${COMMON_TARGET_PROPERTIES})

Expand All @@ -88,24 +111,39 @@ target_link_libraries(mpsc_bench_linearizable
PRIVATE
benchmark::benchmark_main
Threads::Threads
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:atomic>
${ATOMIC_LIBRARY}
)
target_compile_options(mpsc_bench_linearizable ${COMMON_TARGET_PROPERTIES})

add_executable(mpsc_vs_mpmc_benchmark benchmarks/bench_mpsc_vs_mpmc_google.cpp)
target_include_directories(mpsc_vs_mpmc_benchmark
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}
${concurrentqueue_SOURCE_DIR}
)
target_link_libraries(mpsc_vs_mpmc_benchmark
PRIVATE
benchmark::benchmark_main
Threads::Threads
${ATOMIC_LIBRARY}
)
target_compile_options(mpsc_vs_mpmc_benchmark ${COMMON_TARGET_PROPERTIES})

# TEST
add_executable(mpsc_tests tests/test_MPSC.cpp)
target_include_directories(mpsc_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(mpsc_tests PRIVATE GTest::gtest_main GTest::gmock Threads::Threads $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:atomic>)
target_link_libraries(mpsc_tests PRIVATE GTest::gtest_main GTest::gmock Threads::Threads ${ATOMIC_LIBRARY})
include(GoogleTest)
gtest_discover_tests(mpsc_tests)

#EXAMPLE
add_executable(mpsc_log_system_example examples/log_system.cpp)
target_include_directories(mpsc_log_system_example PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(mpsc_log_system_example PRIVATE Threads::Threads $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:atomic>)
target_link_libraries(mpsc_log_system_example PRIVATE Threads::Threads ${ATOMIC_LIBRARY})
target_compile_options(mpsc_log_system_example ${COMMON_TARGET_PROPERTIES})

add_executable(mpsc_command_dispatcher_example examples/command_dispatcher.cpp)
target_include_directories(mpsc_command_dispatcher_example PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(mpsc_command_dispatcher_example PRIVATE Threads::Threads $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:atomic>)
target_compile_options(mpsc_command_dispatcher_example ${COMMON_TARGET_PROPERTIES})
target_link_libraries(mpsc_command_dispatcher_example PRIVATE Threads::Threads ${ATOMIC_LIBRARY})
target_compile_options(mpsc_command_dispatcher_example ${COMMON_TARGET_PROPERTIES})
58 changes: 57 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,64 @@ This scenario tests the throughput when producers use the `enqueue_bulk` interfa
| **moodycamel** | **2** | **1** | **68.9161** | **Best performance in this section (P=2)** | |
| moodycamel | 16 | 1 | 43.4848 | No bulk advantage at 16P |

**Part IV: Additional Google Benchmark Comparison (Clang Release)**

**Part IV: Enqueue/Dequeue Latency**
This comparison is produced by `mpsc_vs_mpmc_benchmark`, using Google Benchmark in a Clang Release build. It uses `moodycamel::ConcurrentQueue` v1.0.5 as a generic MPMC baseline under the same MPSC workloads.

Run on (20 X 2688 MHz CPU s)
CPU Caches:
L1 Data 48 KiB (x10)
L1 Instruction 32 KiB (x10)
L2 Unified 1280 KiB (x10)
L3 Unified 24576 KiB (x1)
Compiler: Clang 22.1.1 Release

Command:

```powershell
cmake -S . -B out/build/clang-local -G Ninja -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release
cmake --build out/build/clang-local --target mpsc_vs_mpmc_benchmark
.\out\build\clang-local\mpsc_vs_mpmc_benchmark.exe --benchmark_min_time=0.1s --benchmark_repetitions=1 --benchmark_counters_tabular=true
```

Uniform single-element enqueue:

| Queue | P (Producers) | C (Consumer) | **Throughput (M items/s)** |
| :--- | :--- | :--- | :--- |
| **daking** | 1 | 1 | **86.78** |
| daking | 2 | 1 | **32.29** |
| daking | 4 | 1 | **32.52** |
| daking | 8 | 1 | 31.16 |
| moodycamel | 1 | 1 | 22.74 |
| moodycamel | 2 | 1 | 27.82 |
| moodycamel | 4 | 1 | 29.79 |
| **moodycamel** | 8 | 1 | **32.07** |

Uneven sequential burst:

| Queue | P (Producers) | C (Consumer) | Relay % | **Throughput (M items/s)** |
| :--- | :--- | :--- | :--- | :--- |
| daking | 4 | 1 | $50.0\%$ | **33.89** |
| daking | 4 | 1 | $90.0\%$ | **61.72** |
| daking | 4 | 1 | $98.0\%$ | **73.72** |
| moodycamel | 4 | 1 | $50.0\%$ | 23.84 |
| moodycamel | 4 | 1 | $90.0\%$ | 22.25 |
| moodycamel | 4 | 1 | $98.0\%$ | 17.64 |

Bulk enqueue:

| Queue | P (Producers) | C (Consumer) | **Throughput (M items/s)** |
| :--- | :--- | :--- | :--- |
| **daking** | 1 | 1 | **102.25** |
| **daking** | 2 | 1 | **102.37** |
| **daking** | 4 | 1 | **85.23** |
| **daking** | 8 | 1 | **77.16** |
| moodycamel | 1 | 1 | 17.02 |
| moodycamel | 2 | 1 | 18.85 |
| moodycamel | 4 | 1 | 18.06 |
| moodycamel | 8 | 1 | 16.02 |

**Part V: Enqueue/Dequeue Latency**

(Based on HdrHistogram, Test on Linux)
We get below performance:
Expand Down
61 changes: 59 additions & 2 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,64 @@ Compiler: MSVC -O2
| **moodycamel** | **2** | **1** | **68.9161** | **本部分最高表现 (P=2)** |
| moodycamel | 16 | 1 | 43.4848 | 16P时无明显批量优势 |

**第四部分:Enqueue/Dequeue Latency**
**第四部分:额外 Google Benchmark 对比(Clang Release)**

此对比由 `mpsc_vs_mpmc_benchmark` 产生,使用 Google Benchmark 和 Clang Release 构建。这里将 `moodycamel::ConcurrentQueue` v1.0.5 作为通用 MPMC 基线,并在相同 MPSC 负载下进行对比。

Run on (20 X 2688 MHz CPU s)
CPU Caches:
L1 Data 48 KiB (x10)
L1 Instruction 32 KiB (x10)
L2 Unified 1280 KiB (x10)
L3 Unified 24576 KiB (x1)
Compiler: Clang 22.1.1 Release

运行命令:

```powershell
cmake -S . -B out/build/clang-local -G Ninja -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release
cmake --build out/build/clang-local --target mpsc_vs_mpmc_benchmark
.\out\build\clang-local\mpsc_vs_mpmc_benchmark.exe --benchmark_min_time=0.1s --benchmark_repetitions=1 --benchmark_counters_tabular=true
```

均匀单元素入队:

| 队列 | P (生产者) | C (消费者) | **吞吐量 (M items/s)** |
| :--- | :--- | :--- | :--- |
| **daking** | 1 | 1 | **86.78** |
| daking | 2 | 1 | **32.29** |
| daking | 4 | 1 | **32.52** |
| daking | 8 | 1 | 31.16 |
| moodycamel | 1 | 1 | 22.74 |
| moodycamel | 2 | 1 | 27.82 |
| moodycamel | 4 | 1 | 29.79 |
| **moodycamel** | 8 | 1 | **32.07** |

不均匀顺序爆发:

| 队列 | P (生产者) | C (消费者) | 接力百分比 | **吞吐量 (M items/s)** |
| :--- | :--- | :--- | :--- | :--- |
| daking | 4 | 1 | $50.0\%$ | **33.89** |
| daking | 4 | 1 | $90.0\%$ | **61.72** |
| daking | 4 | 1 | $98.0\%$ | **73.72** |
| moodycamel | 4 | 1 | $50.0\%$ | 23.84 |
| moodycamel | 4 | 1 | $90.0\%$ | 22.25 |
| moodycamel | 4 | 1 | $98.0\%$ | 17.64 |

批量入队:

| 队列 | P (生产者) | C (消费者) | **吞吐量 (M items/s)** |
| :--- | :--- | :--- | :--- |
| **daking** | 1 | 1 | **102.25** |
| **daking** | 2 | 1 | **102.37** |
| **daking** | 4 | 1 | **85.23** |
| **daking** | 8 | 1 | **77.16** |
| moodycamel | 1 | 1 | 17.02 |
| moodycamel | 2 | 1 | 18.85 |
| moodycamel | 4 | 1 | 18.06 |
| moodycamel | 8 | 1 | 16.02 |

**第五部分:Enqueue/Dequeue Latency**

(此部分基于HdrHistogram,在Linux平台测试)
我们得到了以下延迟表现:
Expand Down Expand Up @@ -323,4 +380,4 @@ daking::MPSC_queue<double> queue3;

## 许可证 (LICENSE)

MPSC\_queue 使用 [MIT 许可证](https://www.google.com/search?q=./LICENSE.txt) 授权。
MPSC\_queue 使用 [MIT 许可证](https://www.google.com/search?q=./LICENSE.txt) 授权。
Loading