-
Notifications
You must be signed in to change notification settings - Fork 26
Expand file tree
/
Copy pathbench.cpp
More file actions
107 lines (89 loc) · 2.69 KB
/
bench.cpp
File metadata and controls
107 lines (89 loc) · 2.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include "Fifo4.hpp"
#include "Fifo4a.hpp"
#include "Fifo4b.hpp"
#include "Fifo5.hpp"
#include "Fifo5a.hpp"
#include "Fifo5b.hpp"
#include "rigtorp.hpp"
#include <benchmark/benchmark.h>
#include <iostream>
#include <thread>
static void pinThread(int cpu) {
if (cpu < 0) {
return;
}
::cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(cpu, &cpuset);
if (::pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset) == -1) {
std::perror("pthread_setaffinity_rp");
std::exit(EXIT_FAILURE);
}
}
constexpr auto cpu1 = 1;
constexpr auto cpu2 = 2;
template<typename T>
struct isRigtorp : std::false_type {};
template<typename ValueT>
struct isRigtorp<rigtorp::SPSCQueue<ValueT>> : std::true_type {};
template<template<typename> class FifoT>
void BM_Fifo(benchmark::State& state) {
using fifo_type = FifoT<std::int_fast64_t>;
using value_type = typename fifo_type::value_type;
constexpr auto fifoSize = 131072;
fifo_type fifo(fifoSize);
auto t = std::jthread([&] {
pinThread(cpu1);
for (auto i = value_type{};; ++i) {
value_type val;
if constexpr(isRigtorp<fifo_type>::value) {
while (!fifo.front());
benchmark::DoNotOptimize(val = *fifo.front());
fifo.pop();
} else {
while (not fifo.pop(val)) {
;
}
benchmark::DoNotOptimize(val);
}
if (val == -1) {
break;
}
if (val != i) {
throw std::runtime_error("invalid value");
}
}
});
auto value = value_type{};
pinThread(cpu2);
for (auto _ : state) {
if constexpr(isRigtorp<fifo_type>::value) {
while (auto again = not fifo.try_push(value)) {
benchmark::DoNotOptimize(again);
}
} else {
while (auto again = not fifo.push(value)) {
benchmark::DoNotOptimize(again);
}
}
++value;
while (auto again = not fifo.empty()) {
benchmark::DoNotOptimize(again);
}
}
state.counters["ops/sec"] = benchmark::Counter(double(value), benchmark::Counter::kIsRate);
state.PauseTiming();
if constexpr(isRigtorp<fifo_type>::value) {
while(not fifo.try_push(-1)) {}
} else {
fifo.push(-1);
}
}
BENCHMARK_TEMPLATE(BM_Fifo, Fifo4);
BENCHMARK_TEMPLATE(BM_Fifo, Fifo4a);
BENCHMARK_TEMPLATE(BM_Fifo, Fifo4b);
BENCHMARK_TEMPLATE(BM_Fifo, Fifo5);
BENCHMARK_TEMPLATE(BM_Fifo, Fifo5a);
BENCHMARK_TEMPLATE(BM_Fifo, Fifo5b);
BENCHMARK_TEMPLATE(BM_Fifo, rigtorp::SPSCQueue);
BENCHMARK_MAIN();