diff --git a/tools/hsbench/engine.h b/tools/hsbench/engine.h index e41f9948..aea1c816 100644 --- a/tools/hsbench/engine.h +++ b/tools/hsbench/engine.h @@ -88,6 +88,8 @@ public: virtual void printStats() const = 0; + virtual void printCsvStats() const = 0; + virtual void sqlStats(SqlDB &db) const = 0; }; diff --git a/tools/hsbench/engine_chimera.cpp b/tools/hsbench/engine_chimera.cpp index 8a15c5be..24a99d61 100644 --- a/tools/hsbench/engine_chimera.cpp +++ b/tools/hsbench/engine_chimera.cpp @@ -187,6 +187,16 @@ void EngineChimera::printStats() const { #endif } +void EngineChimera::printCsvStats() const { + printf(",\"%s\"", compile_stats.signatures.c_str()); + printf(",\"%zu\"", compile_stats.expressionCount); + printf(",\"0x%x\"", compile_stats.crc32); + printf(",\"%zu\"", compile_stats.compiledSize); + printf(",\"%zu\"", compile_stats.scratchSize); + printf(",\"%0.3Lf\"", compile_stats.compileSecs); + printf(",\"%u\"", compile_stats.peakMemorySize); +} + void EngineChimera::sqlStats(SqlDB &sqldb) const { ostringstream crc; crc << "0x" << hex << compile_stats.crc32; diff --git a/tools/hsbench/engine_chimera.h b/tools/hsbench/engine_chimera.h index 8e2cd0f6..187dec8c 100644 --- a/tools/hsbench/engine_chimera.h +++ b/tools/hsbench/engine_chimera.h @@ -89,6 +89,8 @@ public: void printStats() const; + void printCsvStats() const; + void sqlStats(SqlDB &db) const; private: diff --git a/tools/hsbench/engine_hyperscan.cpp b/tools/hsbench/engine_hyperscan.cpp index 79c58f77..c94b42af 100644 --- a/tools/hsbench/engine_hyperscan.cpp +++ b/tools/hsbench/engine_hyperscan.cpp @@ -276,6 +276,17 @@ void EngineHyperscan::printStats() const { #endif } +void EngineHyperscan::printCsvStats() const { + printf(",\"%s\"", compile_stats.signatures.c_str()); + printf(",\"%zu\"", compile_stats.expressionCount); + printf(",\"0x%x\"", compile_stats.crc32); + printf(",\"%zu\"", compile_stats.compiledSize); + printf(",\"%zu\"", compile_stats.streamSize); + printf(",\"%zu\"", compile_stats.scratchSize); + printf(",\"%0.3Lf\"", compile_stats.compileSecs); + printf(",\"%u\"", compile_stats.peakMemorySize); +} + void EngineHyperscan::sqlStats(SqlDB &sqldb) const { ostringstream crc; crc << "0x" << hex << compile_stats.crc32; diff --git a/tools/hsbench/engine_hyperscan.h b/tools/hsbench/engine_hyperscan.h index a8105d75..253ec9aa 100644 --- a/tools/hsbench/engine_hyperscan.h +++ b/tools/hsbench/engine_hyperscan.h @@ -98,6 +98,8 @@ public: void printStats() const; + void printCsvStats() const; + void sqlStats(SqlDB &db) const; private: diff --git a/tools/hsbench/engine_pcre.cpp b/tools/hsbench/engine_pcre.cpp index 85616e98..23ab9d17 100644 --- a/tools/hsbench/engine_pcre.cpp +++ b/tools/hsbench/engine_pcre.cpp @@ -227,6 +227,15 @@ void EnginePCRE::printStats() const { #endif } +void EnginePCRE::printCsvStats() const { + printf(",\"%s\"", compile_stats.signatures.c_str()); + printf(",\"%zu\"", compile_stats.expressionCount); + printf(",\"%zu\"", compile_stats.compiledSize); + printf(",\"%zu\"", compile_stats.scratchSize); + printf(",\"%0.3Lf\"", compile_stats.compileSecs); + printf(",\"%u\"", compile_stats.peakMemorySize); +} + void EnginePCRE::sqlStats(SqlDB &sqldb) const { ostringstream crc; diff --git a/tools/hsbench/engine_pcre.h b/tools/hsbench/engine_pcre.h index 2e7dad9c..d121581f 100644 --- a/tools/hsbench/engine_pcre.h +++ b/tools/hsbench/engine_pcre.h @@ -97,6 +97,8 @@ public: void printStats() const; + void printCsvStats() const; + void sqlStats(SqlDB &db) const; private: diff --git a/tools/hsbench/main.cpp b/tools/hsbench/main.cpp index 4e65c8e0..3349ecc8 100644 --- a/tools/hsbench/main.cpp +++ b/tools/hsbench/main.cpp @@ -98,6 +98,7 @@ bool display_per_scan = false; ScanMode scan_mode = ScanMode::STREAMING; bool useHybrid = false; bool usePcre = false; +bool dumpCsvOut = false; unsigned repeats = 20; string exprPath(""); string corpusFile(""); @@ -211,6 +212,7 @@ void usage(const char *error) { printf(" Benchmark with threads on specified CPUs or CPU" " range.\n"); #endif + printf(" -C Dump CSV output for tput matrix.\n"); printf(" -i DIR Don't compile, load from files in DIR" " instead.\n"); printf(" -w DIR After compiling, save to files in DIR.\n"); @@ -275,6 +277,9 @@ void processArgs(int argc, char *argv[], vector &sigSets, case 'c': corpusFile.assign(optarg); break; + case 'C': + dumpCsvOut = true; + break; case 'd': { unsigned dist; if (!fromString(optarg, dist)) { @@ -849,6 +854,39 @@ void displayResults(const vector> &threads, } } +/** Dump benchmark results to csv. */ +static +void displayCsvResults(const vector> &threads, + const vector &corpus_blocks) { + u64a bytesPerRun = byte_size(corpus_blocks); + u64a matchesPerRun = threads[0]->results[0].matches; + + // Sanity check: all of our results should have the same match count. + for (const auto &t : threads) { + if (!all_of(begin(t->results), end(t->results), + [&matchesPerRun](const ResultEntry &e) { + return e.matches == matchesPerRun; + })) { + printf("\nWARNING: PER-SCAN MATCH COUNTS ARE INCONSISTENT!\n\n"); + break; + } + } + + u64a totalBytes = bytesPerRun * repeats * threads.size(); + u64a totalBlocks = corpus_blocks.size() * repeats * threads.size(); + printf(",\"%0.3f\"", totalSecs); + printf(",\"%0.2Lf\"", calc_mbps(totalSecs, totalBytes)); + + double matchRate = ((double)matchesPerRun * 1024) / bytesPerRun; + printf(",\"%llu\"", matchesPerRun); + printf(",\"%0.3f\"", matchRate); + + double blockRate = (double)totalBlocks / (double)totalSecs; + printf(",\"%0.2f\"", blockRate); + printf("\n"); +} + + /** Dump per-scan throughput data to sql. */ static void sqlPerScanResults(const vector> &threads, @@ -982,7 +1020,9 @@ void runBenchmark(const Engine &db, t->join(); } - if (sqloutFile.empty()) { + if (dumpCsvOut) { + displayCsvResults(threads, corpus_blocks); + } else if (sqloutFile.empty()) { // Display global results. displayResults(threads, corpus_blocks); } else { @@ -1059,7 +1099,9 @@ int HS_CDECL main(int argc, char *argv[]) { exit(1); } - if (sqloutFile.empty()) { + if (dumpCsvOut) { + engine->printCsvStats(); + } else if (sqloutFile.empty()) { // Display global results. engine->printStats(); printf("\n");