#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;
#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;
#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;
ScanMode scan_mode = ScanMode::STREAMING;
bool useHybrid = false;
bool usePcre = false;
+bool dumpCsvOut = false;
unsigned repeats = 20;
string exprPath("");
string corpusFile("");
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");
case 'c':
corpusFile.assign(optarg);
break;
+ case 'C':
+ dumpCsvOut = true;
+ break;
case 'd': {
unsigned dist;
if (!fromString(optarg, dist)) {
}
}
+/** Dump benchmark results to csv. */
+static
+void displayCsvResults(const vector<unique_ptr<ThreadContext>> &threads,
+ const vector<DataBlock> &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<unique_ptr<ThreadContext>> &threads,
t->join();
}
- if (sqloutFile.empty()) {
+ if (dumpCsvOut) {
+ displayCsvResults(threads, corpus_blocks);
+ } else if (sqloutFile.empty()) {
// Display global results.
displayResults(threads, corpus_blocks);
} else {
exit(1);
}
- if (sqloutFile.empty()) {
+ if (dumpCsvOut) {
+ engine->printCsvStats();
+ } else if (sqloutFile.empty()) {
// Display global results.
engine->printStats();
printf("\n");