4#include <gtest/gtest.h>
23 unsigned long long not_atomic = 0;
25 std::thread t1([¬_atomic]() {
26 for (
auto i = 0; i < 1'000'000; ++i) {
31 std::thread t2([¬_atomic]() {
32 for (
auto i = 0; i < 1'000'000; ++i) {
40 EXPECT_NE(not_atomic, 2'000'000);
43 std::atomic<unsigned long long> g_count{ 0};
45 std::thread at1([&g_count]() {
46 for (
auto i = 0; i < 1'000'000; ++i) {
51 std::thread at2([&g_count]() {
52 for (
auto i = 0; i < 1'000'000; ++i) {
60 EXPECT_EQ(g_count, 2'000'000);
115__thread
volatile int you_shall_not_optimize_this;
120 you_shall_not_optimize_this = 42;
124std::chrono::nanoseconds benchmark_threads(
size_t count) {
125 std::vector<std::optional < std::thread>> threads;
126 threads.resize(count);
128 auto before = std::chrono::high_resolution_clock::now();
130 for (
size_t i = 0; i < count; ++i)
131 threads[i] = std::thread{work};
133 for (
size_t i = 0; i < count; ++i)
138 auto after = std::chrono::high_resolution_clock::now();
140 return after - before;
144std::chrono::nanoseconds benchmark_async(
size_t count, std::launch policy) {
145 std::vector<std::optional<std::future<void>>> results;
146 results.resize(count);
148 auto before = std::chrono::high_resolution_clock::now();
150 for (
size_t i = 0; i < count; ++i)
151 results[i] = std::async(policy, work);
153 for (
size_t i = 0; i < count; ++i)
158 auto after = std::chrono::high_resolution_clock::now();
160 return after - before;
164void stat_out(std::chrono::nanoseconds duration) {
165 std::cout <<
"Completed in " << duration.count() <<
"ns (" << std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() <<
"ms)\n";
187 const int count_iteration = 10000;
189 std::cout <<
"Running benchmark iterations " << count_iteration <<
'\n';
190 std::cout <<
"threads: ";
191 stat_out(benchmark_threads(count_iteration));
192 std::cout <<
"async: ";
193 stat_out(benchmark_async(count_iteration, std::launch::async));
194 std::cout <<
"deferred: ";
195 stat_out(benchmark_async(count_iteration, std::launch::deferred));