mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-09-30 19:47:43 +03:00
chimera: hybrid of Hyperscan and PCRE
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Intel Corporation
|
||||
* Copyright (c) 2016-2018, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -31,6 +31,10 @@
|
||||
#include "common.h"
|
||||
#include "data_corpus.h"
|
||||
#include "engine_hyperscan.h"
|
||||
#if defined(HS_HYBRID)
|
||||
#include "engine_chimera.h"
|
||||
#include "engine_pcre.h"
|
||||
#endif
|
||||
#include "expressions.h"
|
||||
#include "sqldb.h"
|
||||
#include "thread_barrier.h"
|
||||
@@ -87,6 +91,8 @@ namespace /* anonymous */ {
|
||||
|
||||
bool display_per_scan = false;
|
||||
ScanMode scan_mode = ScanMode::STREAMING;
|
||||
bool useHybrid = false;
|
||||
bool usePcre = false;
|
||||
unsigned repeats = 20;
|
||||
string exprPath("");
|
||||
string corpusFile("");
|
||||
@@ -102,7 +108,7 @@ typedef void (*thread_func_t)(void *context);
|
||||
|
||||
class ThreadContext : boost::noncopyable {
|
||||
public:
|
||||
ThreadContext(unsigned num_in, const EngineHyperscan &db_in,
|
||||
ThreadContext(unsigned num_in, const Engine &db_in,
|
||||
thread_barrier &tb_in, thread_func_t function_in,
|
||||
vector<DataBlock> corpus_data_in)
|
||||
: num(num_in), results(repeats), engine(db_in),
|
||||
@@ -155,7 +161,7 @@ public:
|
||||
unsigned num;
|
||||
Timer timer;
|
||||
vector<ResultEntry> results;
|
||||
const EngineHyperscan &engine;
|
||||
const Engine &engine;
|
||||
unique_ptr<EngineContext> enginectx;
|
||||
vector<DataBlock> corpus_data;
|
||||
|
||||
@@ -181,6 +187,10 @@ void usage(const char *error) {
|
||||
" (default: streaming).\n");
|
||||
printf(" -V Benchmark in vectored mode"
|
||||
" (default: streaming).\n");
|
||||
#if defined(HS_HYBRID)
|
||||
printf(" -H Benchmark using Chimera (if supported).\n");
|
||||
printf(" -P Benchmark using PCRE (if supported).\n");
|
||||
#endif
|
||||
#ifdef HAVE_DECL_PTHREAD_SETAFFINITY_NP
|
||||
printf(" -T CPU,CPU,... Benchmark with threads on these CPUs.\n");
|
||||
#endif
|
||||
@@ -214,7 +224,7 @@ struct BenchmarkSigs {
|
||||
static
|
||||
void processArgs(int argc, char *argv[], vector<BenchmarkSigs> &sigSets,
|
||||
UNUSED unique_ptr<Grey> &grey) {
|
||||
const char options[] = "-b:c:Cd:e:E:G:hi:n:No:p:sS:Vw:z:"
|
||||
const char options[] = "-b:c:Cd:e:E:G:hHi:n:No:p:PsS:Vw:z:"
|
||||
#ifdef HAVE_DECL_PTHREAD_SETAFFINITY_NP
|
||||
"T:" // add the thread flag
|
||||
#endif
|
||||
@@ -287,6 +297,14 @@ void processArgs(int argc, char *argv[], vector<BenchmarkSigs> &sigSets,
|
||||
usage(nullptr);
|
||||
exit(0);
|
||||
break;
|
||||
case 'H':
|
||||
#if defined(HS_HYBRID)
|
||||
useHybrid = true;
|
||||
#else
|
||||
usage("Hybrid matcher not enabled in this build");
|
||||
exit(1);
|
||||
#endif
|
||||
break;
|
||||
case 'n':
|
||||
if (!fromString(optarg, repeats) || repeats == 0) {
|
||||
usage("Couldn't parse argument to -n flag, should be"
|
||||
@@ -294,6 +312,14 @@ void processArgs(int argc, char *argv[], vector<BenchmarkSigs> &sigSets,
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'P':
|
||||
#if defined(HS_HYBRID)
|
||||
usePcre = true;
|
||||
#else
|
||||
usage("PCRE matcher not enabled in this build");
|
||||
exit(1);
|
||||
#endif
|
||||
break;
|
||||
case 's':
|
||||
in_sigfile = 2;
|
||||
break;
|
||||
@@ -399,6 +425,24 @@ void processArgs(int argc, char *argv[], vector<BenchmarkSigs> &sigSets,
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Constraints on Chimera and PCRE engines
|
||||
if (useHybrid || usePcre) {
|
||||
if (useHybrid && usePcre) {
|
||||
usage("Can't run both Chimera and PCRE.");
|
||||
exit(1);
|
||||
}
|
||||
if (scan_mode != ScanMode::BLOCK) {
|
||||
usage("Must specify block mode in Chimera or PCRE with "
|
||||
"the -N option.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (forceEditDistance || loadDatabases || saveDatabases) {
|
||||
usage("No extended options are supported in Chimera or PCRE.");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Read in any -s signature sets.
|
||||
for (const auto &file : sigFiles) {
|
||||
SignatureSet sigs;
|
||||
@@ -503,7 +547,7 @@ static
|
||||
void benchStreamingInternal(ThreadContext *ctx, vector<StreamInfo> &streams,
|
||||
bool do_compress) {
|
||||
assert(ctx);
|
||||
const EngineHyperscan &e = ctx->engine;
|
||||
const Engine &e = ctx->engine;
|
||||
const vector<DataBlock> &blocks = ctx->corpus_data;
|
||||
vector<char> compress_buf(do_compress ? 1000 : 0);
|
||||
|
||||
@@ -812,7 +856,7 @@ void sqlResults(const vector<unique_ptr<ThreadContext>> &threads,
|
||||
* the same copy of the data.
|
||||
*/
|
||||
static
|
||||
unique_ptr<ThreadContext> makeThreadContext(const EngineHyperscan &db,
|
||||
unique_ptr<ThreadContext> makeThreadContext(const Engine &db,
|
||||
const vector<DataBlock> &blocks,
|
||||
unsigned id,
|
||||
thread_barrier &sync_barrier) {
|
||||
@@ -839,7 +883,7 @@ unique_ptr<ThreadContext> makeThreadContext(const EngineHyperscan &db,
|
||||
|
||||
/** Run the given benchmark. */
|
||||
static
|
||||
void runBenchmark(const EngineHyperscan &db,
|
||||
void runBenchmark(const Engine &db,
|
||||
const vector<DataBlock> &corpus_blocks) {
|
||||
size_t numThreads;
|
||||
bool useAffinity = false;
|
||||
@@ -936,8 +980,18 @@ int main(int argc, char *argv[]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto engine = buildEngineHyperscan(exprMap, scan_mode, s.name,
|
||||
sigName, *grey);
|
||||
unique_ptr<Engine> engine;
|
||||
if (useHybrid) {
|
||||
#if defined(HS_HYBRID)
|
||||
engine = buildEngineChimera(exprMap, s.name, sigName);
|
||||
} else if (usePcre) {
|
||||
engine = buildEnginePcre(exprMap, s.name, sigName);
|
||||
#endif
|
||||
} else {
|
||||
engine = buildEngineHyperscan(exprMap, scan_mode, s.name,
|
||||
sigName, *grey);
|
||||
}
|
||||
|
||||
if (!engine) {
|
||||
printf("Error: expressions failed to compile.\n");
|
||||
exit(1);
|
||||
|
Reference in New Issue
Block a user