-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add performance analysis tool (#167)
Signed-off-by: Michael Mior <[email protected]>
- Loading branch information
1 parent
8242eff
commit 16b8531
Showing
2 changed files
with
229 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,214 @@ | ||
#include <sourcemeta/jsontoolkit/json.h> | ||
#include <sourcemeta/jsontoolkit/jsonl.h> | ||
#include <sourcemeta/jsontoolkit/jsonschema.h> | ||
|
||
#include <sourcemeta/blaze/compiler.h> | ||
#include <sourcemeta/blaze/evaluator.h> | ||
|
||
#include <linux/perf_event.h> | ||
#include <string.h> | ||
#include <sys/ioctl.h> | ||
#include <sys/syscall.h> | ||
|
||
#include <algorithm> // std::sort, std::max | ||
#include <cstdlib> // EXIT_SUCCESS, EXIT_FAILURE | ||
#include <filesystem> // std::filesystem::path | ||
#include <iostream> // std::cerr, std::cout | ||
#include <map> // std::map | ||
#include <utility> // std::pair | ||
#include <vector> // std::vector | ||
|
||
static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid, | ||
int cpu, long group_fd, unsigned long flags) { | ||
long fd = syscall(SYS_perf_event_open, hw_event, pid, cpu, group_fd, flags); | ||
if (fd == -1) { | ||
fprintf(stderr, "Error creating event"); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
return fd; | ||
} | ||
|
||
struct record_t { | ||
uint64_t value; | ||
uint64_t id; | ||
}; | ||
|
||
struct read_format { | ||
uint64_t nr; | ||
record_t values[6]; | ||
}; | ||
|
||
class PerfEvents { | ||
private: | ||
struct perf_event_attr pea; | ||
unsigned long branch_predict_id; | ||
long branch_predict_fd; | ||
unsigned long branch_miss_id; | ||
long branch_miss_fd; | ||
unsigned long cache_access_id; | ||
long cache_access_fd; | ||
unsigned long cache_miss_id; | ||
long cache_miss_fd; | ||
unsigned long cycles_id; | ||
long cycles_fd; | ||
unsigned long instr_id; | ||
long instr_fd; | ||
|
||
void newHWEvent(struct perf_event_attr *newEvent, unsigned long type, | ||
long *fd, long group_fd, unsigned long *id) { | ||
memset(newEvent, 0, sizeof(struct perf_event_attr)); | ||
newEvent->type = PERF_TYPE_HARDWARE; | ||
newEvent->size = sizeof(struct perf_event_attr); | ||
newEvent->config = type; | ||
newEvent->disabled = 1; | ||
newEvent->exclude_kernel = 1; | ||
newEvent->exclude_hv = 1; | ||
newEvent->read_format = PERF_FORMAT_GROUP | PERF_FORMAT_ID; | ||
*fd = perf_event_open(newEvent, 0, -1, group_fd, 0); | ||
ioctl(static_cast<int>(*fd), PERF_EVENT_IOC_ID, id); | ||
} | ||
|
||
public: | ||
PerfEvents() { | ||
newHWEvent(&pea, PERF_COUNT_HW_BRANCH_INSTRUCTIONS, &branch_predict_fd, -1, | ||
&branch_predict_id); | ||
newHWEvent(&pea, PERF_COUNT_HW_BRANCH_MISSES, &branch_miss_fd, | ||
branch_predict_fd, &branch_miss_id); | ||
newHWEvent(&pea, PERF_COUNT_HW_CACHE_REFERENCES, &cache_access_fd, | ||
branch_predict_fd, &cache_access_id); | ||
newHWEvent(&pea, PERF_COUNT_HW_CACHE_MISSES, &cache_miss_fd, | ||
branch_predict_fd, &cache_miss_id); | ||
newHWEvent(&pea, PERF_COUNT_HW_CPU_CYCLES, &cycles_fd, branch_predict_fd, | ||
&cycles_id); | ||
newHWEvent(&pea, PERF_COUNT_HW_INSTRUCTIONS, &instr_fd, branch_predict_fd, | ||
&instr_id); | ||
} | ||
|
||
void start() { | ||
ioctl(static_cast<int>(branch_predict_fd), PERF_EVENT_IOC_RESET, | ||
PERF_IOC_FLAG_GROUP); | ||
ioctl(static_cast<int>(branch_predict_fd), PERF_EVENT_IOC_ENABLE, | ||
PERF_IOC_FLAG_GROUP); | ||
} | ||
|
||
void stop() { | ||
ioctl(static_cast<int>(branch_predict_fd), PERF_EVENT_IOC_DISABLE, | ||
PERF_IOC_FLAG_GROUP); | ||
} | ||
|
||
void print() { | ||
char buf[4096]; | ||
struct read_format *rf = (struct read_format *)buf; | ||
unsigned long branch_predicts = 0; | ||
unsigned long branch_misses = 0; | ||
unsigned long cache_accesses = 0; | ||
unsigned long cache_misses = 0; | ||
unsigned long cycles = 0; | ||
unsigned long instructions = 0; | ||
|
||
if (read(static_cast<int>(branch_predict_fd), buf, sizeof(buf)) <= 0) { | ||
std::cerr << "Error reading performance counters\n"; | ||
return; | ||
} | ||
for (unsigned long i = 0; i < rf->nr; i++) { | ||
if (rf->values[i].id == branch_predict_id) { | ||
branch_predicts = rf->values[i].value; | ||
} else if (rf->values[i].id == branch_miss_id) { | ||
branch_misses = rf->values[i].value; | ||
} else if (rf->values[i].id == cache_access_id) { | ||
cache_accesses = rf->values[i].value; | ||
} else if (rf->values[i].id == cache_miss_id) { | ||
cache_misses = rf->values[i].value; | ||
} else if (rf->values[i].id == cycles_id) { | ||
cycles = rf->values[i].value; | ||
} else if (rf->values[i].id == instr_id) { | ||
instructions = rf->values[i].value; | ||
} | ||
} | ||
|
||
std::cerr << " Cycles: " << cycles << "\n"; | ||
std::cerr << " Instructions: " << instructions << "\n"; | ||
std::cerr << " Cache misses: " << cache_misses << "/" << cache_accesses | ||
<< " = " | ||
<< (static_cast<double>(cache_misses) / | ||
static_cast<double>(cache_accesses) * 100) | ||
<< "%\n"; | ||
std::cerr << "Branch misses: " << branch_misses << "/" << branch_predicts | ||
<< " = " | ||
<< (static_cast<double>(branch_misses) / | ||
static_cast<double>(branch_predicts) * 100) | ||
<< "%\n"; | ||
} | ||
|
||
~PerfEvents() { | ||
close(static_cast<int>(branch_miss_fd)); | ||
close(static_cast<int>(cache_access_fd)); | ||
close(static_cast<int>(cache_miss_fd)); | ||
close(static_cast<int>(cycles_fd)); | ||
close(static_cast<int>(instr_fd)); | ||
close(static_cast<int>(branch_predict_fd)); | ||
} | ||
}; | ||
|
||
bool validate_all(auto &context, const auto &instances, | ||
const auto &schema_template) { | ||
for (std::size_t num = 0; num < instances.size(); num++) { | ||
context.prepare(instances[num]); | ||
const auto result{sourcemeta::blaze::evaluate(schema_template, context)}; | ||
if (!result) { | ||
std::cerr << "Error validating instance " << num << "\n"; | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
auto main(int argc, char **argv) noexcept -> int { | ||
if (argc < 3) { | ||
std::cerr << "Usage: " << argv[0] << " <schema.json> <instances.jsonl>\n"; | ||
return EXIT_FAILURE; | ||
} | ||
|
||
const auto schema{sourcemeta::jsontoolkit::from_file(argv[1])}; | ||
const std::filesystem::path instance_path{argv[2]}; | ||
auto stream{sourcemeta::jsontoolkit::read_file(instance_path)}; | ||
std::vector<sourcemeta::jsontoolkit::JSON> instances; | ||
for (const auto &instance : sourcemeta::jsontoolkit::JSONL{stream}) { | ||
instances.push_back(instance); | ||
} | ||
|
||
const auto schema_template{sourcemeta::blaze::compile( | ||
schema, sourcemeta::jsontoolkit::default_schema_walker, | ||
sourcemeta::jsontoolkit::official_resolver, | ||
sourcemeta::blaze::default_schema_compiler, | ||
sourcemeta::blaze::Mode::FastValidation)}; | ||
|
||
sourcemeta::blaze::EvaluationContext context; | ||
PerfEvents pe; | ||
|
||
pe.start(); | ||
if (!validate_all(context, instances, schema_template)) { | ||
return EXIT_FAILURE; | ||
} | ||
pe.stop(); | ||
|
||
std::cerr << "Cold\n==============================\n"; | ||
pe.print(); | ||
std::cerr << "\n"; | ||
|
||
for (int i = 0; i < 100; i++) { | ||
validate_all(context, instances, schema_template); | ||
} | ||
|
||
pe.start(); | ||
validate_all(context, instances, schema_template); | ||
pe.stop(); | ||
|
||
std::cerr << "Warm\n==============================\n"; | ||
pe.print(); | ||
std::cerr << "\n"; | ||
|
||
return EXIT_SUCCESS; | ||
} |
16b8531
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Benchmark (macos/llvm)
Compiler_Draft6_AdaptiveCard
31512194750.00005
ns/iter31291639375.000046
ns/iter1.01
Compiler_2019_09_OMC_JSON_V2
6585593375.0000305
ns/iter6571359332.999919
ns/iter1.00
Evaluator_Draft4_Meta_1_No_Callback
479.1684987003558
ns/iter484.9673193458705
ns/iter0.99
Evaluator_Draft4_Required_Properties
530.2730714301177
ns/iter539.0459458280483
ns/iter0.98
Evaluator_Draft4_Many_Optional_Properties_Minimal_Match
94.86766141084178
ns/iter94.8542922835574
ns/iter1.00
Evaluator_Draft4_Few_Optional_Properties_Minimal_Match
63.695220379524685
ns/iter61.880114629164865
ns/iter1.03
Evaluator_Draft4_Items_Schema
1181.9031252032964
ns/iter1180.3225593876352
ns/iter1.00
Evaluator_Draft4_Nested_Object
19.798343068835166
ns/iter19.261921241223035
ns/iter1.03
Evaluator_Draft4_Properties_Triad_Optional
1141.3192397796433
ns/iter1124.0000494062226
ns/iter1.02
Evaluator_Draft4_Properties_Triad_Closed
818.2548161402127
ns/iter814.875243466584
ns/iter1.00
Evaluator_Draft4_Properties_Triad_Required
1106.6306291324545
ns/iter1105.6933279017292
ns/iter1.00
Evaluator_Draft4_Non_Recursive_Ref
47.02137830314189
ns/iter46.72936390986542
ns/iter1.01
Evaluator_Draft4_Pattern_Properties_True
1271.1302243511177
ns/iter1267.4226914582648
ns/iter1.00
Evaluator_Draft4_Ref_To_Single_Property
63.18889211938988
ns/iter64.42907097513138
ns/iter0.98
Evaluator_Draft4_Additional_Properties_Type
60.80882714524209
ns/iter60.77650917744998
ns/iter1.00
Evaluator_Draft4_Nested_Oneof
181.62786381163224
ns/iter181.21706332367617
ns/iter1.00
Evaluator_Draft6_Property_Names
511.6327356655807
ns/iter476.4522744410623
ns/iter1.07
Evaluator_Draft7_If_Then_Else
116.6369491746743
ns/iter116.79004373154962
ns/iter1.00
Evaluator_2019_09_Unevaluated_Properties
293.83587642238155
ns/iter294.23217299040033
ns/iter1.00
Evaluator_2019_09_OMC_JSON_V2_1
7691.997256047822
ns/iter7832.185436145683
ns/iter0.98
Evaluator_2020_12_Dynamic_Ref
1104.417952451438
ns/iter1015.7972679089194
ns/iter1.09
This comment was automatically generated by workflow using github-action-benchmark.
16b8531
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Benchmark (linux/llvm)
Compiler_Draft6_AdaptiveCard
56790893003.00001
ns/iter58656327284.000046
ns/iter0.97
Compiler_2019_09_OMC_JSON_V2
10939867380.00001
ns/iter11029887351.000013
ns/iter0.99
Evaluator_Draft4_Meta_1_No_Callback
708.4443165252411
ns/iter710.7231261966888
ns/iter1.00
Evaluator_Draft4_Required_Properties
1092.3617405629136
ns/iter1112.8009491637536
ns/iter0.98
Evaluator_Draft4_Many_Optional_Properties_Minimal_Match
128.66303763236127
ns/iter127.7140790304338
ns/iter1.01
Evaluator_Draft4_Few_Optional_Properties_Minimal_Match
87.95189491608681
ns/iter88.4862823693509
ns/iter0.99
Evaluator_Draft4_Items_Schema
1920.4902560672708
ns/iter1911.050461101069
ns/iter1.00
Evaluator_Draft4_Nested_Object
28.777455469135777
ns/iter29.578458001012798
ns/iter0.97
Evaluator_Draft4_Properties_Triad_Optional
1582.206298108089
ns/iter1599.6877331786256
ns/iter0.99
Evaluator_Draft4_Properties_Triad_Closed
1282.2594556289112
ns/iter1281.2071543018865
ns/iter1.00
Evaluator_Draft4_Properties_Triad_Required
1536.1052152940413
ns/iter1543.4118240099049
ns/iter1.00
Evaluator_Draft4_Non_Recursive_Ref
79.72610094850961
ns/iter77.55470151558609
ns/iter1.03
Evaluator_Draft4_Pattern_Properties_True
2185.679805610496
ns/iter2189.4378076971175
ns/iter1.00
Evaluator_Draft4_Ref_To_Single_Property
87.86658750416937
ns/iter88.80740605559598
ns/iter0.99
Evaluator_Draft4_Additional_Properties_Type
100.87906860174596
ns/iter101.26726209986977
ns/iter1.00
Evaluator_Draft4_Nested_Oneof
270.21452092295823
ns/iter267.99624630436705
ns/iter1.01
Evaluator_Draft6_Property_Names
868.4738749663609
ns/iter893.0530702017048
ns/iter0.97
Evaluator_Draft7_If_Then_Else
156.684481012285
ns/iter157.83150351213658
ns/iter0.99
Evaluator_2019_09_Unevaluated_Properties
405.707624096159
ns/iter381.6299097601865
ns/iter1.06
Evaluator_2019_09_OMC_JSON_V2_1
11745.321912161859
ns/iter11920.596438518918
ns/iter0.99
Evaluator_2020_12_Dynamic_Ref
1370.8886737163166
ns/iter1371.8075738365008
ns/iter1.00
This comment was automatically generated by workflow using github-action-benchmark.
16b8531
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Benchmark (linux/gcc)
Evaluator_2020_12_Dynamic_Ref
1344.1606814875038
ns/iter1318.1500423007574
ns/iter1.02
Evaluator_2019_09_Unevaluated_Properties
405.4976934655142
ns/iter404.693585570588
ns/iter1.00
Evaluator_2019_09_OMC_JSON_V2_1
14011.34828874391
ns/iter14251.693383130672
ns/iter0.98
Evaluator_Draft7_If_Then_Else
147.00701287172322
ns/iter146.22661436310665
ns/iter1.01
Evaluator_Draft6_Property_Names
1549.9154636478509
ns/iter1529.4874233370401
ns/iter1.01
Evaluator_Draft4_Meta_1_No_Callback
765.984595110889
ns/iter760.7858064613256
ns/iter1.01
Evaluator_Draft4_Required_Properties
1979.3782391516186
ns/iter1989.231567244302
ns/iter1.00
Evaluator_Draft4_Many_Optional_Properties_Minimal_Match
137.50732488893286
ns/iter132.06443705765284
ns/iter1.04
Evaluator_Draft4_Few_Optional_Properties_Minimal_Match
101.9158988583964
ns/iter97.01944931205378
ns/iter1.05
Evaluator_Draft4_Items_Schema
1543.1457215451028
ns/iter1578.0392720741252
ns/iter0.98
Evaluator_Draft4_Nested_Object
26.532762130649374
ns/iter26.284575160213535
ns/iter1.01
Evaluator_Draft4_Properties_Triad_Optional
1576.4661976222112
ns/iter1590.10073623296
ns/iter0.99
Evaluator_Draft4_Properties_Triad_Closed
1276.2614857915337
ns/iter1288.4176723249411
ns/iter0.99
Evaluator_Draft4_Properties_Triad_Required
1611.566642539611
ns/iter1627.5158728683743
ns/iter0.99
Evaluator_Draft4_Non_Recursive_Ref
99.71594890373909
ns/iter94.87291019850115
ns/iter1.05
Evaluator_Draft4_Pattern_Properties_True
2233.591012781577
ns/iter2235.2400302961555
ns/iter1.00
Evaluator_Draft4_Ref_To_Single_Property
103.44113876053524
ns/iter100.94591594000536
ns/iter1.02
Evaluator_Draft4_Additional_Properties_Type
154.33849291780498
ns/iter149.52410450289906
ns/iter1.03
Evaluator_Draft4_Nested_Oneof
230.7571959791813
ns/iter230.21273567899905
ns/iter1.00
Compiler_2019_09_OMC_JSON_V2
11342681725.000034
ns/iter11219970020.999994
ns/iter1.01
Compiler_Draft6_AdaptiveCard
65464620907.00004
ns/iter65180781747.000084
ns/iter1.00
This comment was automatically generated by workflow using github-action-benchmark.
16b8531
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Benchmark (macos/gcc)
Compiler_Draft6_AdaptiveCard
46922742128.37219
ns/iter47036839008.3313
ns/iter1.00
Compiler_2019_09_OMC_JSON_V2
8682300090.789795
ns/iter8476594924.926758
ns/iter1.02
Evaluator_Draft4_Meta_1_No_Callback
538.7234763086497
ns/iter569.0227235350648
ns/iter0.95
Evaluator_Draft4_Required_Properties
698.6922035595182
ns/iter717.9275369612184
ns/iter0.97
Evaluator_Draft4_Many_Optional_Properties_Minimal_Match
118.96387949943826
ns/iter120.25284606693224
ns/iter0.99
Evaluator_Draft4_Few_Optional_Properties_Minimal_Match
85.16968636525901
ns/iter77.67931911630862
ns/iter1.10
Evaluator_Draft4_Items_Schema
1480.822805467645
ns/iter1281.0423439448111
ns/iter1.16
Evaluator_Draft4_Nested_Object
25.850546284402498
ns/iter25.957688501326025
ns/iter1.00
Evaluator_Draft4_Properties_Triad_Optional
1444.3984107481813
ns/iter1407.342136951041
ns/iter1.03
Evaluator_Draft4_Properties_Triad_Closed
1207.8554077321808
ns/iter1217.9130513485698
ns/iter0.99
Evaluator_Draft4_Properties_Triad_Required
1321.6423781004469
ns/iter1326.2886692967925
ns/iter1.00
Evaluator_Draft4_Non_Recursive_Ref
65.25831147803784
ns/iter64.81134443170322
ns/iter1.01
Evaluator_Draft4_Pattern_Properties_True
1816.1310844520062
ns/iter1736.4175322710178
ns/iter1.05
Evaluator_Draft4_Ref_To_Single_Property
80.99254078185204
ns/iter82.12192422407297
ns/iter0.99
Evaluator_Draft4_Additional_Properties_Type
80.13360809045443
ns/iter78.85375325367309
ns/iter1.02
Evaluator_Draft4_Nested_Oneof
206.55504730128118
ns/iter206.2100502897471
ns/iter1.00
Evaluator_Draft6_Property_Names
646.4913459780602
ns/iter658.8780703121685
ns/iter0.98
Evaluator_Draft7_If_Then_Else
134.49424217709515
ns/iter127.54048709705796
ns/iter1.05
Evaluator_2019_09_Unevaluated_Properties
349.05206879172823
ns/iter357.12492685689654
ns/iter0.98
Evaluator_2019_09_OMC_JSON_V2_1
8131.000411906226
ns/iter8122.096170701714
ns/iter1.00
Evaluator_2020_12_Dynamic_Ref
1188.9650883391766
ns/iter1201.3678142356707
ns/iter0.99
This comment was automatically generated by workflow using github-action-benchmark.
16b8531
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Benchmark (windows/msvc)
Compiler_Draft6_AdaptiveCard
119554981099.99985
ns/iter120297761299.99982
ns/iter0.99
Compiler_2019_09_OMC_JSON_V2
25187896599.99993
ns/iter25351995300
ns/iter0.99
Evaluator_Draft4_Meta_1_No_Callback
1485.9815017942667
ns/iter1489.2087053571652
ns/iter1.00
Evaluator_Draft4_Required_Properties
1472.102624061446
ns/iter1460.889955357203
ns/iter1.01
Evaluator_Draft4_Many_Optional_Properties_Minimal_Match
353.4558014935187
ns/iter361.4998104464673
ns/iter0.98
Evaluator_Draft4_Few_Optional_Properties_Minimal_Match
243.78141490089942
ns/iter244.88160213375423
ns/iter1.00
Evaluator_Draft4_Items_Schema
3281.1004392195073
ns/iter3197.3524958640774
ns/iter1.03
Evaluator_Draft4_Nested_Object
110.70003124999062
ns/iter111.81003124999478
ns/iter0.99
Evaluator_Draft4_Properties_Triad_Optional
5168.441071428934
ns/iter5183.61428571471
ns/iter1.00
Evaluator_Draft4_Properties_Triad_Closed
4192.753396092088
ns/iter4224.37713197426
ns/iter0.99
Evaluator_Draft4_Properties_Triad_Required
5135.4959999980565
ns/iter5160.114285715167
ns/iter1.00
Evaluator_Draft4_Non_Recursive_Ref
250.66546428571914
ns/iter252.65964285714355
ns/iter0.99
Evaluator_Draft4_Pattern_Properties_True
8138.133311903805
ns/iter8195.38216347032
ns/iter0.99
Evaluator_Draft4_Ref_To_Single_Property
246.23328571424608
ns/iter247.46239285710607
ns/iter1.00
Evaluator_Draft4_Additional_Properties_Type
335.49188054564263
ns/iter337.81745306830015
ns/iter0.99
Evaluator_Draft4_Nested_Oneof
558.7333035714031
ns/iter562.9029464285752
ns/iter0.99
Evaluator_Draft6_Property_Names
1534.4743303573289
ns/iter1535.709693879318
ns/iter1.00
Evaluator_Draft7_If_Then_Else
371.3410051176826
ns/iter374.8181652110928
ns/iter0.99
Evaluator_2019_09_Unevaluated_Properties
957.7372510102197
ns/iter935.5809216156622
ns/iter1.02
Evaluator_2019_09_OMC_JSON_V2_1
16923.797480785342
ns/iter16963.599086602462
ns/iter1.00
Evaluator_2020_12_Dynamic_Ref
3147.303125000381
ns/iter3117.904464285662
ns/iter1.01
This comment was automatically generated by workflow using github-action-benchmark.