@@ -75,7 +75,6 @@ void exit_usage(string message) {
75
75
}
76
76
77
77
struct option_struct {
78
- architecture arch = architecture::UNSUPPORTED;
79
78
bool stage1_only = false ;
80
79
81
80
int32_t iterations = 400 ;
@@ -86,7 +85,7 @@ struct option_struct {
86
85
option_struct (int argc, char **argv) {
87
86
int c;
88
87
89
- while ((c = getopt (argc, argv, " vtn:i:a: s:" )) != -1 ) {
88
+ while ((c = getopt (argc, argv, " vtn:i:s:" )) != -1 ) {
90
89
switch (c) {
91
90
case ' n' :
92
91
iterations = atoi (optarg);
@@ -97,12 +96,6 @@ struct option_struct {
97
96
case ' v' :
98
97
verbose = true ;
99
98
break ;
100
- case ' a' :
101
- arch = parse_architecture (optarg);
102
- if (arch == architecture::UNSUPPORTED) {
103
- exit_usage (string (" Unsupported option value -a " ) + optarg + " : expected -a HASWELL, WESTMERE or ARM64" );
104
- }
105
- break ;
106
99
case ' s' :
107
100
if (!strcmp (optarg, " stage1" )) {
108
101
stage1_only = true ;
@@ -113,15 +106,9 @@ struct option_struct {
113
106
}
114
107
break ;
115
108
default :
116
- exit_error (" Unexpected argument " + c );
109
+ exit_error (string ( " Unexpected argument " ) + std::string ( 1 , static_cast < char >(c)) );
117
110
}
118
111
}
119
-
120
- // If architecture is not specified, pick the best supported architecture by default
121
- if (arch == architecture::UNSUPPORTED) {
122
- arch = find_best_supported_architecture ();
123
- }
124
- dom::parser::use_implementation (arch);
125
112
}
126
113
127
114
template <typename F>
@@ -150,20 +137,20 @@ struct feature_benchmarker {
150
137
benchmarker struct23;
151
138
benchmarker struct23_miss;
152
139
153
- feature_benchmarker (const simdjson::implementation &parser, event_collector& collector) :
154
- utf8 (" jsonexamples/ generated/utf-8.json" , parser , collector),
155
- utf8_miss (" jsonexamples/ generated/utf-8-miss.json" , parser , collector),
156
- escape (" jsonexamples/ generated/escape.json" , parser , collector),
157
- escape_miss (" jsonexamples/ generated/escape-miss.json" , parser , collector),
158
- empty (" jsonexamples/ generated/0-structurals.json" , parser , collector),
159
- empty_miss (" jsonexamples/ generated/0-structurals-miss.json" , parser , collector),
160
- struct7 (" jsonexamples/ generated/7-structurals.json" , parser , collector),
161
- struct7_miss (" jsonexamples/ generated/7-structurals-miss.json" , parser , collector),
162
- struct7_full (" jsonexamples/ generated/7-structurals-full.json" , parser , collector),
163
- struct15 (" jsonexamples/ generated/15-structurals.json" , parser , collector),
164
- struct15_miss (" jsonexamples/ generated/15-structurals-miss.json" , parser , collector),
165
- struct23 (" jsonexamples/ generated/23-structurals.json" , parser , collector),
166
- struct23_miss (" jsonexamples/ generated/23-structurals-miss.json" , parser , collector)
140
+ feature_benchmarker (event_collector& collector) :
141
+ utf8 (SIMDJSON_BENCHMARK_DATA_DIR " generated/utf-8.json" , collector),
142
+ utf8_mis
F438
s (SIMDJSON_BENCHMARK_DATA_DIR " generated/utf-8-miss.json" , collector),
143
+ escape (SIMDJSON_BENCHMARK_DATA_DIR " generated/escape.json" , collector),
144
+ escape_miss (SIMDJSON_BENCHMARK_DATA_DIR " generated/escape-miss.json" , collector),
145
+ empty (SIMDJSON_BENCHMARK_DATA_DIR " generated/0-structurals.json" , collector),
146
+ empty_miss (SIMDJSON_BENCHMARK_DATA_DIR " generated/0-structurals-miss.json" , collector),
147
+ struct7 (SIMDJSON_BENCHMARK_DATA_DIR " generated/7-structurals.json" , collector),
148
+ struct7_miss (SIMDJSON_BENCHMARK_DATA_DIR " generated/7-structurals-miss.json" , collector),
149
+ struct7_full (SIMDJSON_BENCHMARK_DATA_DIR " generated/7-structurals-full.json" , collector),
150
+ struct15 (SIMDJSON_BENCHMARK_DATA_DIR " generated/15-structurals.json" , collector),
151
+ struct15_miss (SIMDJSON_BENCHMARK_DATA_DIR " generated/15-structurals-miss.json" , collector),
152
+ struct23 (SIMDJSON_BENCHMARK_DATA_DIR " generated/23-structurals.json" , collector),
153
+ struct23_miss (SIMDJSON_BENCHMARK_DATA_DIR " generated/23-structurals-miss.json" , collector)
167
154
{
168
155
169
156
}
@@ -185,7 +172,7 @@ struct feature_benchmarker {
185
172
}
186
173
187
174
double cost_per_block (BenchmarkStage stage, const benchmarker& feature, size_t feature_blocks, const benchmarker& base) const {
188
- return (feature[stage].best .elapsed_ns () - base[stage].best .elapsed_ns ()) / feature_blocks;
175
+ return (feature[stage].best .elapsed_ns () - base[stage].best .elapsed_ns ()) / double ( feature_blocks) ;
189
176
}
190
177
191
178
// Whether we're recording cache miss and branch miss events
@@ -195,7 +182,7 @@ struct feature_benchmarker {
195
182
196
183
// Base cost of any block (including empty ones)
197
184
double base_cost (BenchmarkStage stage) const {
198
- return (empty[stage].best .elapsed_ns () / empty.stats ->blocks );
185
+ return (empty[stage].best .elapsed_ns () / double ( empty.stats ->blocks ) );
199
186
}
200
187
201
188
// Extra cost of a 1-7 structural block over an empty block
@@ -209,7 +196,7 @@ struct feature_benchmarker {
209
196
// Rate of 1-7-structural misses per 8-structural flip
210
197
double struct1_7_miss_rate (BenchmarkStage stage) const {
211
198
if (!has_events ()) { return 1 ; }
212
- return double ( struct7_miss[stage].best .branch_misses () - struct7[stage].best .branch_misses ()) / struct7_miss.stats ->blocks_with_1_structural_flipped ;
199
+ return struct7_miss[stage].best .branch_misses () - struct7[stage].best .branch_misses () / double ( struct7_miss.stats ->blocks_with_1_structural_flipped ) ;
213
200
}
214
201
215
202
// Extra cost of an 8-15 structural block over a 1-7 structural block
@@ -223,7 +210,7 @@ struct feature_benchmarker {
223
210
// Rate of 8-15-structural misses per 8-structural flip
224
211
double struct8_15_miss_rate (BenchmarkStage stage) const {
225
212
if (!has_events ()) { return 1 ; }
226
- return double (struct15_miss[stage].best .branch_misses () - struct15[stage].best .branch_misses ()) / struct15_miss.stats ->blocks_with_8_structurals_flipped ;
213
+ return double (struct15_miss[stage].best .branch_misses () - struct15[stage].best .branch_misses ()) / double ( struct15_miss.stats ->blocks_with_8_structurals_flipped ) ;
227
214
}
228
215
229
216
// Extra cost of a 16+-structural block over an 8-15 structural block (actual varies based on # of structurals!)
@@ -237,7 +224,7 @@ struct feature_benchmarker {
237
224
// Rate of 16-structural misses per 16-structural flip
238
225
double struct16_miss_rate (BenchmarkStage stage) const {
239
226
if (!has_events ()) { return 1 ; }
240
- return double (struct23_miss[stage].best .branch_misses () - struct23[stage].best .branch_misses ()) / struct23_miss.stats ->blocks_with_16_structurals_flipped ;
227
+ return double (struct23_miss[stage].best .branch_misses () - struct23[stage].best .branch_misses ()) / double ( struct23_miss.stats ->blocks_with_16_structurals_flipped ) ;
241
228
}
242
229
243
230
// Extra cost of having UTF-8 in a block
@@ -251,7 +238,7 @@ struct feature_benchmarker {
251
238
// Rate of UTF-8 misses per UTF-8 flip
252
239
double utf8_miss_rate (BenchmarkStage stage) const {
253
240
if (!has_events ()) { return 1 ; }
254
- return double (utf8_miss[stage].best .branch_misses () - utf8[stage].best .branch_misses ()) / utf8_miss.stats ->blocks_with_utf8_flipped ;
241
+ return double (utf8_miss[stage].best .branch_misses () - utf8[stage].best .branch_misses ()) / double ( utf8_miss.stats ->blocks_with_utf8_flipped ) ;
255
242
}
256
243
257
244
// Extra cost of having escapes in a block
@@ -265,39 +252,39 @@ struct feature_benchmarker {
265
252
// Rate of escape misses per escape flip
266
253
double escape_miss_rate (BenchmarkStage stage) const {
267
254
if (!has_events ()) { return 1 ; }
268
- return double (escape_miss[stage].best .branch_misses () - escape[stage].best .branch_misses ()) / escape_miss.stats ->blocks_with_escapes_flipped ;
255
+ return double (escape_miss[stage].best .branch_misses () - escape[stage].best .branch_misses ()) / double ( escape_miss.stats ->blocks_with_escapes_flipped ) ;
269
256
}
270
257
271
258
double calc_expected_feature_cost (BenchmarkStage stage, const benchmarker& file) const {
272
259
// Expected base ns/block (empty)
273
260
json_stats& stats = *file.stats ;
274
- double expected = base_cost (stage) * stats.blocks ;
275
- expected += struct1_7_cost (stage) * stats.blocks_with_1_structural ;
276
- expected += utf8_cost (stage) * stats.blocks_with_utf8 ;
277
- expected += escape_cost (stage) * stats.blocks_with_escapes ;
278
- expected += struct8_15_cost (stage) * stats.blocks_with_8_structurals ;
279
- expected += struct16_cost (stage) * stats.blocks_with_16_structurals ;
280
- return expected / stats.blocks ;
261
+ double expected = base_cost (stage) * double ( stats.blocks ) ;
262
+ expected += struct1_7_cost (stage) * double ( stats.blocks_with_1_structural ) ;
263
+ expected += utf8_cost (stage) * double ( stats.blocks_with_utf8 ) ;
264
+ expected += escape_cost (stage) * double ( stats.blocks_with_escapes ) ;
265
+ expected += struct8_15_cost (stage) * double ( stats.blocks_with_8_structurals ) ;
266
+ expected += struct16_cost (stage) * double ( stats.blocks_with_16_structurals ) ;
267
+ return expected / double ( stats.blocks ) ;
281
268
}
282
269
283
270
double calc_expected_miss_cost (BenchmarkStage stage, const benchmarker& file) const {
284
271
// Expected base ns/block (empty)
285
272
json_stats& stats = *file.stats ;
286
- double expected = struct1_7_miss_cost (stage) * stats.blocks_with_1_structural_flipped * struct1_7_miss_rate (stage);
287
- expected += utf8_miss_cost (stage) * stats.blocks_with_utf8_flipped * utf8_miss_rate (stage);
288
- expected += escape_miss_cost (stage) * stats.blocks_with_escapes_flipped * escape_miss_rate (stage);
289
- expected += struct8_15_miss_cost (stage) * stats.blocks_with_8_structurals_flipped * struct8_15_miss_rate (stage);
290
- expected += struct16_miss_cost (stage) * stats.blocks_with_16_structurals_flipped * struct16_miss_rate (stage);
291
- return expected / stats.blocks ;
273
+ double expected = struct1_7_miss_cost (stage) * double ( stats.blocks_with_1_structural_flipped ) * struct1_7_miss_rate (stage);
274
+ expected += utf8_miss_cost (stage) * double ( stats.blocks_with_utf8_flipped ) * utf8_miss_rate (stage);
275
+ expected += escape_miss_cost (stage) * double ( stats.blocks_with_escapes_flipped ) * escape_miss_rate (stage);
276
+ expected += struct8_15_miss_cost (stage) * double ( stats.blocks_with_8_structurals_flipped ) * struct8_15_miss_rate (stage);
277
+ expected += struct16_miss_cost (stage) * double ( stats.blocks_with_16_structurals_flipped ) * struct16_miss_rate (stage);
278
+ return expected / double ( stats.blocks ) ;
292
279
}
293
280
294
281
double calc_expected_misses (BenchmarkStage stage, const benchmarker& file) const {
295
282
json_stats& stats = *file.stats ;
296
- double expected = stats.blocks_with_1_structural_flipped * struct1_7_miss_rate (stage);
297
- expected += stats.blocks_with_utf8_flipped * utf8_miss_rate (stage);
298
- expected += stats.blocks_with_escapes_flipped * escape_miss_rate (stage);
299
- expected += stats.blocks_with_8_structurals_flipped * struct8_15_miss_rate (stage);
300
- expected += stats.blocks_with_16_structurals_flipped * struct16_miss_rate (stage);
283
+ double expected = double ( stats.blocks_with_1_structural_flipped ) * struct1_7_miss_rate (stage);
284
+ expected += double ( stats.blocks_with_utf8_flipped ) * utf8_miss_rate (stage);
285
+ expected += double ( stats.blocks_with_escapes_flipped ) * escape_miss_rate (stage);
286
+ expected += double ( stats.blocks_with_8_structurals_flipped ) * struct8_15_miss_rate (stage);
287
+ expected += double ( stats.blocks_with_16_structurals_flipped ) * struct16_miss_rate (stage);
301
288
return expected;
302
289
}
303
290
@@ -364,10 +351,10 @@ struct feature_benchmarker {
364
351
};
365
352
366
353
void print_file_effectiveness (BenchmarkStage stage, const char * filename, const benchmarker& results, const feature_benchmarker& features) {
367
- double actual = results[stage].best .elapsed_ns () / results.stats ->blocks ;
354
+ double actual = results[stage].best .elapsed_ns () / double ( results.stats ->blocks ) ;
368
355
double calc = features.calc_expected (stage, results);
369
- uint64_t actual_misses = results[stage].best .branch_misses ();
370
- uint64_t calc_misses = uint64_t ( features.calc_expected_misses (stage, results) );
356
+ double actual_misses = results[stage].best .branch_misses ();
357
+ double calc_misses = features.calc_expected_misses (stage, results);
371
358
double calc_miss_cost = features.calc_expected_miss_cost (stage, results);
372
359
printf (" | %-8s " , benchmark_stage_name (stage));
373
360
printf (" | %-15s " , filename);
@@ -376,10 +363,10 @@ void print_file_effectiveness(BenchmarkStage stage, const char* filename, const
376
363
printf (" | %8.3g " , calc);
377
364
printf (" | %8.3g " , actual);
378
365
printf (" | %+8.3g " , actual - calc);
379
- printf (" | %13lu " , calc_misses);
366
+ printf (" | %13llu " , ( long long unsigned )( calc_misses) );
380
367
if (features.has_events ()) {
381
- printf (" | %13lu " , actual_misses);
382
- printf (" | %+13ld " , int64_t (actual_misses - calc_misses));
368
+ printf (" | %13llu " , ( long long unsigned )( actual_misses) );
369
+ printf (" | %+13lld " , ( long long int ) (actual_misses - calc_misses));
383
370
double miss_adjustment = calc_miss_cost * (double (int64_t (actual_misses - calc_misses)) / calc_misses);
384
371
printf (" | %8.3g " , calc_miss_cost + miss_adjustment);
385
372
printf (" | %+8.3g " , actual - (calc + miss_adjustment));
@@ -401,9 +388,9 @@ int main(int argc, char *argv[]) {
401
388
402
389
// Set up benchmarkers by reading all files
403
390
feature_benchmarker features (collector);
404
- benchmarker gsoc_2018 (" jsonexamples/ gsoc-2018.json" , collector);
405
- benchmarker twitter (" jsonexamples/ twitter.json" , collector);
406
- benchmarker random (" jsonexamples/ random.json" , collector);
391
+ benchmarker gsoc_2018 (SIMDJSON_BENCHMARK_DATA_DIR " gsoc-2018.json" , collector);
392
+ benchmarker twitter (SIMDJSON_BENCHMARK_DATA_DIR " twitter.json" , collector);
393
+ benchmarker random (SIMDJSON_BENCHMARK_DATA_DIR " random.json" , collector);
407
394
408
395
// Run the benchmarks
409
396
progress_bar progress (options.iterations , 100 );
0 commit comments