Comparing performance of a task queued to an existing thread vs. new thread for each task.
修订版 | 86b23c6decb1fd0261cd67ffe6d3e9771fefb7fc (tree) |
---|---|
时间 | 2017-03-24 06:14:49 |
作者 | Eric Hopper <hopper@omni...> |
Commiter | Eric Hopper |
Use Moody Camel's lock free queue implementation.
@@ -2,6 +2,8 @@ | ||
2 | 2 | #include <thread> |
3 | 3 | #include <future> |
4 | 4 | #include <iostream> |
5 | +#include "readerwriterqueue.h" | |
6 | +#include <stdexcept> | |
5 | 7 | |
6 | 8 | extern void do_something(); |
7 | 9 |
@@ -27,17 +29,38 @@ | ||
27 | 29 | return count / interval; |
28 | 30 | } |
29 | 31 | |
32 | + | |
33 | +static bool end_thread_flag = false; | |
34 | + | |
35 | +void end_thread() | |
36 | +{ | |
37 | + end_thread_flag = true; | |
38 | +} | |
39 | + | |
40 | +void worker_thread(::moodycamel::BlockingReaderWriterQueue<the_call_t> &to_me, | |
41 | + ::moodycamel::BlockingReaderWriterQueue<bool> &from_me) | |
42 | +{ | |
43 | + while (!end_thread_flag) { | |
44 | + the_call_t a_call; | |
45 | + to_me.wait_dequeue(a_call); | |
46 | + a_call(); | |
47 | + if (!from_me.enqueue(true)) { | |
48 | + throw ::std::runtime_error("Unable to queue notification!"); | |
49 | + } | |
50 | + } | |
51 | +} | |
52 | + | |
30 | 53 | int main() |
31 | 54 | { |
32 | 55 | using ::std::cout; |
33 | 56 | using ::std::async; |
34 | 57 | using ::std::thread; |
35 | 58 | using ::std::launch; |
36 | - cout << " Do nothing calls per second: " | |
59 | + cout << " Do nothing calls per second: " | |
37 | 60 | << calls_per_second([]() { }, 5) << '\n'; |
38 | - cout << " Empty calls per second: " | |
61 | + cout << " Empty calls per second: " | |
39 | 62 | << calls_per_second([]() { do_something(); }, 5) << '\n'; |
40 | - cout << " New thread calls per second: " | |
63 | + cout << " New thread calls per second: " | |
41 | 64 | << calls_per_second( |
42 | 65 | []() { |
43 | 66 | thread t{ do_something }; |
@@ -46,7 +69,7 @@ | ||
46 | 69 | 5 |
47 | 70 | ) |
48 | 71 | << '\n'; |
49 | - cout << "Async launch calls per second: " | |
72 | + cout << " Async launch calls per second: " | |
50 | 73 | << calls_per_second( |
51 | 74 | []() { |
52 | 75 | auto fut = async(launch::async | launch::deferred, do_something); |
@@ -55,5 +78,28 @@ | ||
55 | 78 | 5 |
56 | 79 | ) |
57 | 80 | << '\n'; |
81 | + { | |
82 | + ::moodycamel::BlockingReaderWriterQueue<the_call_t> from_main; | |
83 | + ::moodycamel::BlockingReaderWriterQueue<bool> to_main; | |
84 | + thread worker{ [&from_main, &to_main]() { worker_thread(from_main, to_main); } }; | |
85 | + cout << "Worker thread calls per second: " | |
86 | + << calls_per_second( | |
87 | + [&from_main, &to_main]() { | |
88 | + if (!from_main.enqueue(do_something)) { | |
89 | + throw ::std::runtime_error("Unable to send request to worker."); | |
90 | + } | |
91 | + bool dummy = false; | |
92 | + to_main.wait_dequeue(dummy); | |
93 | + }, | |
94 | + 5 | |
95 | + ) | |
96 | + << '\n'; | |
97 | + from_main.enqueue(end_thread); | |
98 | + { | |
99 | + bool dummy; | |
100 | + to_main.wait_dequeue(dummy); | |
101 | + } | |
102 | + worker.join(); | |
103 | + } | |
58 | 104 | return 0; |
59 | 105 | } |