micro-benchmarks for shufti, trufle and noodle added

This commit is contained in:
apostolos 2021-08-24 14:05:12 +03:00 committed by Konstantinos Margaritis
parent 08357a096c
commit 904a94fbe5
8 changed files with 360 additions and 3 deletions

View File

@ -1400,3 +1400,8 @@ option(BUILD_EXAMPLES "Build Hyperscan example code (default TRUE)" TRUE)
if(BUILD_EXAMPLES)
add_subdirectory(examples)
endif()
option(BUILD_BENCHMARKS "Build benchmarks (default TRUE)" TRUE)
if(BUILD_BENCHMARKS)
add_subdirectory(benchmarks)
endif()

View File

@ -0,0 +1,4 @@
add_executable(benchmarks benchmarks.cpp shufti.cpp truffle.cpp noodle.cpp)
set_source_files_properties(shufti.cpp PROPERTIES COMPILE_FLAGS
"-Wall -Wno-unused-variable")
target_link_libraries(benchmarks hs)

119
benchmarks/benchmarks.cpp Normal file
View File

@ -0,0 +1,119 @@
#include "benchmarks.hpp"
#include <iostream>
#include <string>
#include <string.h>
#include <time.h>
int main(){
int sizes[]= { 10000, 16000, 32000, 64000, 120000, 1232896, 1600000, 2000000, 2500000, 3500000, 100000000, 150000000, 250000000, 350000000, 500000000};
int iters[]= { 10000, 16000, 32000, 64000, 120000, 5000, 3000, 3000, 3000, 2000, 25, 25, 3, 3, 2};
int exp_len[]= { 10000, 16000, 32000, 64000, 120000, 600000, 1000000, 1000000, 1500000, 3500000, 1000000, 10000000, 20000000, 30000000, 40000000};
const char charset[] = "aAaAaAaAAAaaaaAAAAaaaaAAAAAAaaaAAaaa";
std::cout<<std::endl <<"\x1B[33m shuftiExec Benchmarks(kbytes) \x1B[0m"<<std::endl;
for (int i = 0; i < 5; i++) {
shufti_benchmarks(sizes[i],iters[i],exp_len[i],false);
shufti_benchmarks(sizes[i],iters[i],exp_len[i],true);
}
std::cout<<std::endl <<"\x1B[33m rshuftiExec Benchmarks(kbytes) \x1B[0m"<<std::endl;
for (int i = 0; i < 5; i++) {
rshufti_benchmarks(sizes[i],iters[i],exp_len[i],false);
rshufti_benchmarks(sizes[i],iters[i],exp_len[i],true);
}
std::cout<<std::endl <<"\x1B[33m truffleExec Benchmarks(kbytes) \x1B[0m"<<std::endl;
for (int i = 0; i < 5; i++) {
truffle_benchmarks(sizes[i],iters[i],exp_len[i],false);
truffle_benchmarks(sizes[i],iters[i],exp_len[i],true);
}
std::cout<<std::endl <<"\x1B[33m rtruffleExec Benchmarks(kbytes) \x1B[0m"<<std::endl;
for (int i = 0; i < 5; i++) {
rtruffle_benchmarks(sizes[i],iters[i],exp_len[i],false);
rtruffle_benchmarks(sizes[i],iters[i],exp_len[i],true);
}
std::cout<<std::endl <<"\x1B[33m shuftiExec Benchmarks(Mbytes) \x1B[0m"<<std::endl;
for (int i = 5; i < 10; i++) {
shufti_benchmarks(sizes[i],iters[i],exp_len[i],false);
shufti_benchmarks(sizes[i],iters[i],exp_len[i],true);
}
std::cout<<std::endl <<"\x1B[33m rshuftiExec Benchmarks(Mbytes) \x1B[0m"<<std::endl;
for (int i = 5; i < 10; i++) {
rshufti_benchmarks(sizes[i],iters[i],exp_len[i],false);
rshufti_benchmarks(sizes[i],iters[i],exp_len[i],true);
}
std::cout<<std::endl <<"\x1B[33m truffleExec Benchmarks(Mbytes) \x1B[0m"<<std::endl;
for (int i = 5; i < 10; i++) {
truffle_benchmarks(sizes[i],iters[i],exp_len[i],false);
truffle_benchmarks(sizes[i],iters[i],exp_len[i],true);
}
std::cout<<std::endl <<"\x1B[33m rtruffleExec Benchmarks(Mbytes) \x1B[0m"<<std::endl;
for (int i = 5; i < 10; i++) {
rtruffle_benchmarks(sizes[i],iters[i],exp_len[i],false);
rtruffle_benchmarks(sizes[i],iters[i],exp_len[i],true);
}
std::cout<<std::endl <<"\x1B[33m shuftiExec Benchmarks(Gbytes) \x1B[0m"<<std::endl;
for (int i = 10; i < 15; i++) {
shufti_benchmarks(sizes[i],iters[i],exp_len[i],false);
shufti_benchmarks(sizes[i],iters[i],exp_len[i],true);
// run time 2.5 min
}
std::cout<<std::endl <<"\x1B[33m rshuftiExec Benchmarks(Gbytes) \x1B[0m"<<std::endl;
for (int i = 10; i < 15; i++) {
rshufti_benchmarks(sizes[i],iters[i],exp_len[i],false);
rshufti_benchmarks(sizes[i],iters[i],exp_len[i],true);
}
std::cout<<std::endl <<"\x1B[33m truffleExec Benchmarks(Gbytes) \x1B[0m"<<std::endl;
for (int i = 10; i < 15; i++) {
truffle_benchmarks(sizes[i],iters[i],exp_len[i],false);
truffle_benchmarks(sizes[i],iters[i],exp_len[i],true);
}
std::cout<<std::endl <<"\x1B[33m rtruffleExec Benchmarks(Gbytes) \x1B[0m"<<std::endl;
for (int i = 10; i < 15; i++) {
rtruffle_benchmarks(sizes[i],iters[i],exp_len[i],false);
rtruffle_benchmarks(sizes[i],iters[i],exp_len[i],true);
}
/*noodle_benchmarks(120000, 32000, "aaaA", 4, 1); ---> kill
noodle_benchmarks(2500000, 5000, "AaAAaaaA", 8, 1); ---> kill
γενικά όταν βάζω ένα string μεγέθους > 4 για nocase = 1 κάνει kill.
*/
std::cout<<std::endl <<"\x1B[33m noodle Benchmarks(kbytes) \x1B[0m"<<std::endl;
for (int char_len = 1; char_len < 9; char_len++) {
char *str = new char[char_len];
for (int j=0; j<char_len; j++) {
srand (time(NULL));
int key = rand() % + 36 ;
str[char_len] = charset[key];
str[char_len + 1] = '\0';
}
for (int i=0; i<5; i++){
noodle_benchmarks(sizes[i], iters[i], str,char_len,0);
}
delete [] str;
}
std::cout<<std::endl <<"\x1B[33m noodle Benchmarks(Mbytes) \x1B[0m"<<std::endl;
for (int char_len = 1; char_len < 9; char_len++) {
char *str = new char[char_len];
for (int j=0; j<char_len; j++) {
srand (time(NULL));
int key = rand() % + 36 ;
str[char_len] = charset[key];
str[char_len + 1] = '\0';
}
for (int i=5; i<10; i++){
noodle_benchmarks(sizes[i], iters[i], str,char_len,0);
}
delete [] str;
}
std::cout<<std::endl <<"\x1B[33m noodle Benchmarks(Gbytes) \x1B[0m"<<std::endl;
for (int char_len = 1; char_len < 9; char_len++) {
char *str = new char[char_len];
for (int j=0; j<char_len; j++) {
srand (time(NULL));
int key = rand() % + 36 ;
str[char_len] = charset[key];
str[char_len + 1] = '\0';
}
for (int i=10; i<15; i++){
noodle_benchmarks(sizes[i], iters[i], str,char_len,0);
}
delete [] str;
}
return 0;
}

View File

@ -0,0 +1,5 @@
void shufti_benchmarks(int size, int loops, int M, bool has_match);
void rshufti_benchmarks(int size, int loops, int M, bool has_match);
void truffle_benchmarks(int size, int loops, int M, bool has_match);
void rtruffle_benchmarks(int size, int loops, int M, bool has_match);
void noodle_benchmarks(int size, int M, const char *lit_str, int lit_len, char nocase);

51
benchmarks/noodle.cpp Normal file
View File

@ -0,0 +1,51 @@
#include <iostream>
#include "ue2common.h"
#include "benchmarks.hpp"
#include "hwlm/noodle_build.h"
#include "hwlm/noodle_engine.h"
#include "hwlm/hwlm.h"
#include "hwlm/hwlm_literal.h"
#include "scratch.h"
#include <vector>
#include <chrono>
struct hlmMatchEntry {
size_t to;
u32 id;
hlmMatchEntry(size_t end, u32 identifier) :
to(end), id(identifier) {}
};
std::vector<hlmMatchEntry> ctxt;
static
hwlmcb_rv_t hlmSimpleCallback(size_t to, u32 id,
UNUSED struct hs_scratch *scratch) {
DEBUG_PRINTF("match @%zu = %u\n", to, id);
ctxt.push_back(hlmMatchEntry(to, id));
return HWLM_CONTINUE_MATCHING;
}
void noodle_benchmarks(int size, int M, const char *lit_str, int lit_len, char nocase){
ctxt.clear();
u8 *data = new u8[size];
memset(data, 'a', size);
double total_sec = 0;
u32 id = 1000;
ue2::hwlmLiteral lit(std::string(lit_str, lit_len), nocase, id);
auto n = ue2::noodBuildTable(lit);
assert(n != nullptr);
struct hs_scratch scratch;
for (int i = 0; i < M; i++){
auto start = std::chrono::steady_clock::now();
noodExec(n.get(), data, size, 0, hlmSimpleCallback, &scratch);
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> noodExec_elapsed_seconds = end-start;
total_sec += noodExec_elapsed_seconds.count();
}
total_sec /= M;
std::cout<<"\x1B[35m Case with match in random pos and size: "<<size<<" lit_len: "<<lit_len<<" nocase: "<<(int)nocase<<"\x1B[36m noodExec elapsetime: \x1B[0m"<<total_sec<<std::endl;
}

86
benchmarks/shufti.cpp Normal file
View File

@ -0,0 +1,86 @@
#include "nfa/shufti.h"
#include "benchmarks.hpp"
#include <iostream>
#include <chrono>
#include <time.h>
/*
#define RST "\x1B[0m"
#define KRED "\x1B[31m"
#define KGRN "\x1B[32m"
#define KYEL "\x1B[33m"
#define KBLU "\x1B[34m"
#define KMAG "\x1B[35m"
#define KCYN "\x1B[36m"
#define KWHT "\x1B[37m"
*/
void shufti_benchmarks(int size, int loops, int M, bool has_match) {
m128 lo, hi;
char *kt1 = new char[size];
memset(kt1,'b',size);
double total_sec = 0;
if (has_match){
int pos = 0;
for(int j=0; j<M; j++){
kt1[pos] = 'b';
srand (time(NULL));
pos = rand() % size + 0;
kt1[pos] = 'a';
auto start = std::chrono::steady_clock::now();
for (int i = 0; i < loops/M; i++) {
shuftiExec(lo, hi, (u8 *)kt1 + i, (u8 *)kt1 + strlen(kt1));
}
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> shuftiExec_elapsed_seconds = end-start;
total_sec += shuftiExec_elapsed_seconds.count();
}
total_sec /= M;
std::cout<<"\x1B[35m Case with match in random pos and size: "<<size<<" for "<<loops<<" loops ("<< M <<" random possisions checked):"<<"\x1B[36m shuftiExec elapsetime: \x1B[0m"<<total_sec<<std::endl;
} else {
auto start = std::chrono::steady_clock::now();
for (int i = 0; i < loops; i++) {
shuftiExec(lo, hi, (u8 *)kt1 + i, (u8 *)kt1 + strlen(kt1));
}
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> shuftiExec_elapsed_seconds = end-start;
total_sec += shuftiExec_elapsed_seconds.count();
std::cout<<"\x1B[35m Case with no match in random pos and size: "<<size<<" for "<<loops<<" loops:"<<"\x1B[36m shuftiExec elapsetime: \x1B[0m"<<total_sec<<std::endl;
}
delete [] kt1;
}
void rshufti_benchmarks(int size, int loops, int M, bool has_match) {
m128 lo, hi;
char *kt1 = new char[size];
memset(kt1,'b',size);
double total_sec = 0;
if (has_match){
int pos = 0;
for(int j=0; j<M; j++){
kt1[pos] = 'b';
srand (time(NULL));
pos = rand() % size + 0;
kt1[pos] = 'a';
auto start = std::chrono::steady_clock::now();
for (int i = 0; i < loops/M; i++) {
rshuftiExec(lo, hi, (u8 *)kt1 + i, (u8 *)kt1 + strlen(kt1));
}
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> shuftiExec_elapsed_seconds = end-start;
total_sec += shuftiExec_elapsed_seconds.count();
}
total_sec /= M;
std::cout<<"\x1B[35m Case with match in random pos and size: "<<size<<" for "<<loops<<" loops ("<< M <<" random possisions checked):"<<"\x1B[36m rshuftiExec elapsetime: \x1B[0m"<<total_sec<<std::endl;
} else {
auto start = std::chrono::steady_clock::now();
for (int i = 0; i < loops; i++) {
rshuftiExec(lo, hi, (u8 *)kt1 + i, (u8 *)kt1 + strlen(kt1));
}
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> shuftiExec_elapsed_seconds = end-start;
total_sec += shuftiExec_elapsed_seconds.count();
std::cout<<"\x1B[35m Case with no match in random pos and size: "<<size<<" for "<<loops<<" loops:"<<"\x1B[36m rshuftiExec elapsetime: \x1B[0m"<<total_sec<<std::endl;
}
delete [] kt1;
}

87
benchmarks/truffle.cpp Normal file
View File

@ -0,0 +1,87 @@
#include "nfa/truffle.h"
#include "benchmarks.hpp"
#include <iostream>
#include <chrono>
#include <time.h>
/*
#define RST "\x1B[0m"
#define KRED "\x1B[31m"
#define KGRN "\x1B[32m"
#define KYEL "\x1B[33m"
#define KBLU "\x1B[34m"
#define KMAG "\x1B[35m"
#define KCYN "\x1B[36m"
#define KWHT "\x1B[37m"
*/
void truffle_benchmarks(int size, int loops, int M, bool has_match) {
m128 lo, hi;
char *kt1 = new char[size];
memset(kt1,'b',size);
double total_sec = 0;
if (has_match){
int pos = 0;
for(int j=0; j<M; j++){
kt1[pos] = 'b';
srand (time(NULL));
pos = rand() % size + 0;
kt1[pos] = 'a';
auto start = std::chrono::steady_clock::now();
for (int i = 0; i < loops/M; i++) {
truffleExec(lo, hi, (u8 *)kt1 + i, (u8 *)kt1 + strlen(kt1));
}
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> shuftiExec_elapsed_seconds = end-start;
total_sec += shuftiExec_elapsed_seconds.count();
}
total_sec /= M;
std::cout<<"\x1B[35m Case with match in random pos and size: "<<size<<" for "<<loops<<" loops ("<< M <<" random possisions checked):"<<"\x1B[36m truffleExec elapsetime: \x1B[0m"<<total_sec<<std::endl;
} else {
auto start = std::chrono::steady_clock::now();
for (int i = 0; i < loops; i++) {
truffleExec(lo, hi, (u8 *)kt1 + i, (u8 *)kt1 + strlen(kt1));
}
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> shuftiExec_elapsed_seconds = end-start;
total_sec += shuftiExec_elapsed_seconds.count();
std::cout<<"\x1B[35m Case with no match in random pos and size: "<<size<<" for "<<loops<<" loops:"<<"\x1B[36m truffleExec elapsetime: \x1B[0m"<<total_sec<<std::endl;
}
delete [] kt1;
}
void rtruffle_benchmarks(int size, int loops, int M, bool has_match) {
m128 lo, hi;
char *kt1 = new char[size];
memset(kt1,'b',size);
double total_sec = 0;
if (has_match){
int pos = 0;
for(int j=0; j<M; j++){
kt1[pos] = 'b';
srand (time(NULL));
pos = rand() % size + 0;
kt1[pos] = 'a';
auto start = std::chrono::steady_clock::now();
for (int i = 0; i < loops/M; i++) {
rtruffleExec(lo, hi, (u8 *)kt1 + i, (u8 *)kt1 + strlen(kt1));
}
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> shuftiExec_elapsed_seconds = end-start;
total_sec += shuftiExec_elapsed_seconds.count();
}
total_sec /= M;
std::cout<<"\x1B[35m Case with match in random pos and size: "<<size<<" for "<<loops<<" loops ("<< M <<" random possisions checked):"<<"\x1B[36m rtruffleExec elapsetime: \x1B[0m"<<total_sec<<std::endl;
} else {
auto start = std::chrono::steady_clock::now();
for (int i = 0; i < loops; i++) {
rtruffleExec(lo, hi, (u8 *)kt1 + i, (u8 *)kt1 + strlen(kt1));
}
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> shuftiExec_elapsed_seconds = end-start;
total_sec += shuftiExec_elapsed_seconds.count();
std::cout<<"\x1B[35m Case with no match in random pos and size: "<<size<<" for "<<loops<<" loops:"<<"\x1B[36m rtruffleExec elapsetime: \x1B[0m"<<total_sec<<std::endl;
}
delete [] kt1;
}

View File

@ -293,7 +293,7 @@ TEST(SuperVectorUtilsTest,pshufb128c) {
/*Define LSHIFT128_128 macro*/
#define TEST_LSHIFT128_128(buf, vec, v, l) { \
auto v_shifted = SP.lshift128(l); \
auto v_shifted = v.lshift128(l); \
for (int i=15; i>= l; --i) { \
buf[i] = vec[i-l]; \
} \
@ -317,7 +317,7 @@ TEST(SuperVectorUtilsTest,LShift128_128c){
/*Define RSHIFT128_128 macro*/
#define TEST_RSHIFT128_128(buf, vec, v, l) { \
auto v_shifted = SP.rshift128(l); \
auto v_shifted = v.rshift128(l); \
for (int i=0; i<16-l; i++) { \
buf[i] = vec[i+l]; \
} \
@ -966,7 +966,7 @@ TEST(SuperVectorUtilsTest,RShift512c){
/*Define RSHIFT128_512 macro*/
#define TEST_RSHIFT128_512(buf, vec, v, l) { \
auto v_shifted = SP.rshift128(l); \
auto v_shifted = v.rshift128(l); \
for (int i=0; i<16-l; i++) { \
buf[i] = vec[i+l]; \
buf[i+16] = vec[(i+16)+l]; \