valFuzz 1.2.0
Loading...
Searching...
No Matches
benchmark.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2// Author: Giovanni Santini
3// Mail: giovanni.santini@proton.me
4// Github: @San7o
5
7
8namespace valfuzz
9{
10
11std::atomic<bool> &get_save_to_file()
12{
13#if __cplusplus >= 202002L // C++20
14 constinit
15#endif
16 static std::atomic<bool>
17 save_to_file = false;
18 return save_to_file;
19}
20
21#if defined(__linux__)
22unsigned long get_cache_l3_size()
23{
24 std::ifstream file("/sys/devices/system/cpu/cpu0/cache/index2/size");
25 std::string size_str;
26 if (file.is_open())
27 {
28 std::getline(file, size_str);
29 file.close();
30 }
31
32 char unit = size_str.back();
33 size_str.pop_back();
34 unsigned long cache_size = std::stoul(size_str);
35
36 switch (unit)
37 {
38 case 'K':
39 cache_size *= 1024;
40 break;
41 case 'M':
42 cache_size *= 1024 * 1024;
43 break;
44 default:
45 break;
46 }
47
48 return cache_size;
49}
50#elif defined(_WIN32) || defined(_WIN64)
51unsigned long get_cache_l3_size()
52{
53 return 0;
54}
55#else
56unsigned long get_cache_l3_size()
57{
58 return 0;
59}
60#endif
61
63{
64#if __cplusplus >= 202002L // C++20
65 constinit
66#endif
67 static bool do_benchmarks = false;
68 return do_benchmarks;
69}
70
71std::deque<benchmark_pair> &get_benchmarks()
72{
73 static std::deque<benchmark_pair> registered_benchmarks = {};
74 return registered_benchmarks;
75}
76
78{
79#if __cplusplus >= 202002L // C++20
80 constinit
81#endif
82 static int num_iterations_benchmark = 100000;
83 return num_iterations_benchmark;
84}
85
86unsigned long get_num_benchmarks()
87{
88 auto &benchmarks = get_benchmarks();
89 return benchmarks.size();
90}
91
93{
94#if __cplusplus >= 202002L // C++20
95 constinit
96#endif
97 static bool run_one_benchmark = false;
98 return run_one_benchmark;
99}
100
101std::string &get_one_benchmark()
102{
103 static std::string one_benchmark = "";
104 return one_benchmark;
105}
106
107std::ofstream &get_save_file()
108{
109 static std::ofstream output;
110 return output;
111}
112
113void set_save_to_file(bool save_to_file)
114{
115 auto &save_to_file_ref = get_save_to_file();
116 save_to_file_ref = save_to_file;
117}
118
119void set_save_file(const std::filesystem::path &output_dir)
120{
121 auto &output_dir_ref = get_save_file();
122 output_dir_ref = std::ofstream(output_dir);
123 if (!output_dir_ref.is_open())
124 {
125 std::lock_guard<std::mutex> lock(get_stream_mutex());
126 std::cout << "Could not open file " << output_dir << "\n";
127 std::exit(1);
128 }
129 output_dir_ref << "name,space,min,max,median,mean,sd,q1,q3\n";
130}
131
132void add_benchmark(const std::string &name, benchmark_function benchmark)
133{
134 auto &benchmarks = get_benchmarks();
135 benchmarks.push_back({name, benchmark});
136}
137
138void set_do_benchmarks(bool do_benchmarks)
139{
140 auto &do_benchmarks_ref = get_do_benchmarks();
141 do_benchmarks_ref = do_benchmarks;
142}
143
144void set_num_iterations_benchmark(int num_iterations)
145{
146 auto &num_iterations_benchmark = get_num_iterations_benchmark();
147 num_iterations_benchmark = num_iterations;
148}
149
150void set_run_one_benchmark(bool run_one_benchmark)
151{
152 auto &run_one_benchmark_ref = get_run_one_benchmark();
153 run_one_benchmark_ref = run_one_benchmark;
154}
155
156void set_one_benchmark(const std::string &one_benchmark)
157{
158 auto &one_benchmark_ref = get_one_benchmark();
159 one_benchmark_ref = one_benchmark;
160}
161
163{
164 const size_t bigger_than_cachesize = get_cache_l3_size() * 2;
165 if (bigger_than_cachesize == 0)
166 return;
167 long *p;
168 p = new long[bigger_than_cachesize];
169 {
170 std::lock_guard<std::mutex> lock(get_stream_mutex());
171 std::cout << "Cache size: " << get_cache_l3_size() << "\n";
172 }
173 for (auto &benchmark : get_benchmarks())
174 {
175 // flush cache
176 for (size_t i = 0; i < bigger_than_cachesize; i++)
177 {
178 p[i] = std::rand();
179 }
180
182 {
183 if (benchmark.first != get_one_benchmark())
184 continue;
185 }
186
187 if (get_verbose())
188 {
189 std::lock_guard<std::mutex> lock(get_stream_mutex());
190 std::cout << "Running benchmark: " << benchmark.first << "\n";
191 std::cout << std::flush;
192 }
193 else
194 // this is needed or the benchmark will totally be shit, don't ask me
195 // why
196 {
197 std::lock_guard<std::mutex> lock(get_stream_mutex());
198 std::cout << std::flush;
199 }
200 benchmark.second(benchmark.first);
201 }
202 if (bigger_than_cachesize != 0)
203 delete[] p;
204}
205
206} // namespace valfuzz
int & get_num_iterations_benchmark()
Definition benchmark.cpp:77
bool & get_do_benchmarks()
Definition benchmark.cpp:62
void set_save_file(const std::filesystem::path &save_to_file_path)
void set_num_iterations_benchmark(int num_iterations_benchmark)
bool & get_run_one_benchmark()
Definition benchmark.cpp:92
void set_save_to_file(bool save_to_file)
std::atomic< bool > & get_verbose()
Definition common.cpp:20
void set_one_benchmark(const std::string &one_benchmark)
std::ofstream & get_save_file()
void set_do_benchmarks(bool do_benchmarks)
void add_benchmark(const std::string &name, benchmark_function benchmark)
unsigned long get_num_benchmarks()
Definition benchmark.cpp:86
void run_benchmarks()
std::atomic< bool > & get_save_to_file()
Definition benchmark.cpp:11
std::string & get_one_benchmark()
unsigned long get_cache_l3_size()
Definition benchmark.cpp:56
std::function< void(std::string)> benchmark_function
Definition benchmark.hpp:98
std::deque< benchmark_pair > & get_benchmarks()
Definition benchmark.cpp:71
void set_run_one_benchmark(bool run_one_benchmark)
std::mutex & get_stream_mutex()
Definition common.cpp:11