1#include <iostream>
2#include <iomanip>
3
4#include <IO/ReadHelpers.h>
5
6#include <Common/Stopwatch.h>
7#include <Common/Exception.h>
8#include <Common/ThreadPool.h>
9
10
11int value = 0;
12
13static void f() { ++value; }
14static void * g(void *) { f(); return {}; }
15
16
17namespace DB
18{
19 namespace ErrorCodes
20 {
21 extern const int PTHREAD_ERROR;
22 }
23}
24
25
26template <typename F>
27void test(size_t n, const char * name, F && kernel)
28{
29 value = 0;
30
31 Stopwatch watch;
32 Stopwatch watch_one;
33 double max_seconds = 0;
34
35 std::cerr << name << ":\n";
36
37 for (size_t i = 0; i < n; ++i)
38 {
39 watch_one.restart();
40
41 kernel();
42
43 watch_one.stop();
44 if (watch_one.elapsedSeconds() > max_seconds)
45 max_seconds = watch_one.elapsedSeconds();
46 }
47
48 watch.stop();
49
50 std::cerr
51 << std::fixed << std::setprecision(2)
52 << n << " ops in "
53 << watch.elapsedSeconds() << " sec., "
54 << n / watch.elapsedSeconds() << " ops/sec., "
55 << "avg latency: " << watch.elapsedSeconds() / n * 1000000 << " μs, "
56 << "max latency: " << max_seconds * 1000000 << " μs "
57 << "(res = " << value << ")"
58 << std::endl;
59}
60
61
62int main(int argc, char ** argv)
63{
64 size_t n = argc == 2 ? DB::parse<UInt64>(argv[1]) : 100000;
65
66 test(n, "Create and destroy ThreadPool each iteration", []
67 {
68 ThreadPool tp(1);
69 tp.scheduleOrThrowOnError(f);
70 tp.wait();
71 });
72
73 test(n, "pthread_create, pthread_join each iteration", []
74 {
75 pthread_t thread;
76 if (pthread_create(&thread, nullptr, g, nullptr))
77 DB::throwFromErrno("Cannot create thread.", DB::ErrorCodes::PTHREAD_ERROR);
78 if (pthread_join(thread, nullptr))
79 DB::throwFromErrno("Cannot join thread.", DB::ErrorCodes::PTHREAD_ERROR);
80 });
81
82 test(n, "Create and destroy std::thread each iteration", []
83 {
84 std::thread thread(f);
85 thread.join();
86 });
87
88 {
89 ThreadPool tp(1);
90
91 test(n, "Schedule job for Threadpool each iteration", [&tp]
92 {
93 tp.scheduleOrThrowOnError(f);
94 tp.wait();
95 });
96 }
97
98 {
99 ThreadPool tp(128);
100
101 test(n, "Schedule job for Threadpool with 128 threads each iteration", [&tp]
102 {
103 tp.scheduleOrThrowOnError(f);
104 tp.wait();
105 });
106 }
107
108 return 0;
109}
110