#include "json_parser.h" #include "event_counter.h" #include #include #ifndef _MSC_VER #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "linux-perf-events.h" #ifdef __linux__ #include #endif //#define DEBUG #include "simdjson/common_defs.h" #include "simdjson/isadetection.h" #include "simdjson/jsonioutil.h" #include "simdjson/jsonparser.h" #include "simdjson/parsedjson.h" #include "simdjson/stage1_find_marks.h" #include "simdjson/stage2_build_tape.h" #include #include "benchmarker.h" using namespace simdjson; using std::cerr; using std::cout; using std::endl; using std::string; using std::to_string; using std::vector; using std::ostream; using std::ofstream; using std::exception; // Stash the exe_name in main() for functions to use char* exe_name; void print_usage(ostream& out) { out << "Usage: " << exe_name << " [-vt] [-n #] [-s STAGE] [-a ARCH] ..." << endl; out << endl; out << "Runs the parser against the given json files in a loop, measuring speed and other statistics." << endl; out << endl; out << "Options:" << endl; out << endl; out << "-n # - Number of iterations per file. Default: 200" << endl; out << "-i # - Number of times to iterate a single file before moving to the next. Default: 20" << endl; out << "-t - Tabbed data output" << endl; out << "-v - Verbose output." << endl; out << "-s STAGE - Stop after the given stage." << endl; out << " -s stage1 - Stop after find_structural_bits." << endl; out << " -s all - Run all stages." << endl; out << " -s allfast - Run all stages." << endl; out << "-a ARCH - Use the parser with the designated architecture (HASWELL, WESTMERE" << endl; out << " or ARM64). By default, detects best supported architecture." << endl; out << "-o - Estimate the overall speed as stage 1 + stage 2 instead of a rerun of both" << endl; } void exit_usage(string message) { cerr << message << endl; cerr << endl; print_usage(cerr); exit(EXIT_FAILURE); } struct option_struct { vector files; Architecture architecture = Architecture::UNSUPPORTED; bool stage1_only = false; int32_t iterations = 200; int32_t iteration_step = 50; bool verbose = false; bool tabbed_output = false; bool rerunbothstages = true; option_struct(int argc, char **argv) { #ifndef _MSC_VER int c; while ((c = getopt(argc, argv, "vtn:i:a:s:")) != -1) { switch (c) { case 'n': iterations = atoi(optarg); break; case 'i': iteration_step = atoi(optarg); break; case 't': tabbed_output = true; break; case 'v': verbose = true; break; case 'a': architecture = parse_architecture(optarg); if (architecture == Architecture::UNSUPPORTED) { exit_usage(string("Unsupported option value -a ") + optarg + ": expected -a HASWELL, WESTMERE or ARM64"); } break; case 's': if (!strcmp(optarg, "stage1")) { stage1_only = true; } else if (!strcmp(optarg, "all")) { stage1_only = false; rerunbothstages = true; // for safety } else if (!strcmp(optarg, "allfast")) { stage1_only = false; rerunbothstages = false; } else { exit_usage(string("Unsupported option value -s ") + optarg + ": expected -s stage1 or all"); } break; default: // reaching here means an argument was given to getopt() which did not have a case label exit_error("Unexpected argument - missing case for option "+ std::string(1,static_cast(c))+ " (programming error)"); } } #else int optind = 1; #endif // If architecture is not specified, pick the best supported architecture by default if (architecture == Architecture::UNSUPPORTED) { architecture = find_best_supported_architecture(); } // All remaining arguments are considered to be files for (int i=optind; i benchmarkers; for (size_t i=0; ifilename << " iterations #" << iteration << "-" << (iteration+options.iteration_step-1) << endl; benchmarkers[f]->run_iterations(options.iteration_step, true, false); } } } else { for (int iteration = 0; iteration < options.iterations; iteration += options.iteration_step) { if (!options.verbose) { progress.print(iteration); } // Benchmark each file once per iteration for (size_t f=0; ffilename << " iterations #" << iteration << "-" << (iteration+options.iteration_step-1) << endl; benchmarkers[f]->run_iterations(options.iteration_step, false, options.rerunbothstages); } } } if (!options.verbose) { progress.erase(); } for (size_t i=0; iprint(options.tabbed_output); delete benchmarkers[i]; } return EXIT_SUCCESS; }