]> git.ipfire.org Git - thirdparty/vectorscan.git/commitdiff
micro-benchmarks for shufti, trufle and noodle added
authorapostolos <apostolos.tapsas@vectorcamp.gr>
Tue, 24 Aug 2021 11:05:12 +0000 (14:05 +0300)
committerKonstantinos Margaritis <konstantinos@vectorcamp.gr>
Tue, 12 Oct 2021 08:51:34 +0000 (11:51 +0300)
CMakeLists.txt
benchmarks/CMakeLists.txt [new file with mode: 0644]
benchmarks/benchmarks.cpp [new file with mode: 0644]
benchmarks/benchmarks.hpp [new file with mode: 0644]
benchmarks/noodle.cpp [new file with mode: 0644]
benchmarks/shufti.cpp [new file with mode: 0644]
benchmarks/truffle.cpp [new file with mode: 0644]
unit/internal/supervector.cpp

index b9d8f72526587fc192ee11e0cb3349b61c631aa3..2b999a000c39124c67b7a6038f701c2167debfbe 100644 (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()
diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt
new file mode 100644 (file)
index 0000000..debfc0c
--- /dev/null
@@ -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)
\ No newline at end of file
diff --git a/benchmarks/benchmarks.cpp b/benchmarks/benchmarks.cpp
new file mode 100644 (file)
index 0000000..8354a2d
--- /dev/null
@@ -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;
+}
\ No newline at end of file
diff --git a/benchmarks/benchmarks.hpp b/benchmarks/benchmarks.hpp
new file mode 100644 (file)
index 0000000..f27a7e0
--- /dev/null
@@ -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);
\ No newline at end of file
diff --git a/benchmarks/noodle.cpp b/benchmarks/noodle.cpp
new file mode 100644 (file)
index 0000000..3e6e2d9
--- /dev/null
@@ -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;    
+}
\ No newline at end of file
diff --git a/benchmarks/shufti.cpp b/benchmarks/shufti.cpp
new file mode 100644 (file)
index 0000000..4d214e3
--- /dev/null
@@ -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;
+}
diff --git a/benchmarks/truffle.cpp b/benchmarks/truffle.cpp
new file mode 100644 (file)
index 0000000..a28b28c
--- /dev/null
@@ -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;
+}
\ No newline at end of file
index ef152f690323c15910b23179baaa7b9e6e15e529..68fda015120e0d20ffc4c3aa4e08d2d06ac133d8 100644 (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];                 \