* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <iostream>
#include <chrono>
+#include <cstdlib>
#include <cstring>
#include <ctime>
-#include <cstdlib>
-#include <memory>
#include <functional>
+#include <iostream>
+#include <memory>
#include "benchmarks.hpp"
-#define MAX_LOOPS 1000000000
-#define MAX_MATCHES 5
-#define N 8
+#define MAX_LOOPS 1000000000
+#define MAX_MATCHES 5
+#define N 8
struct hlmMatchEntry {
size_t to;
u32 id;
- hlmMatchEntry(size_t end, u32 identifier) :
- to(end), id(identifier) {}
+ 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) {
+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;
}
-template<typename InitFunc, typename BenchFunc>
-static void run_benchmarks(int size, int loops, int max_matches, bool is_reverse, MicroBenchmark &bench, InitFunc &&init, BenchFunc &&func) {
+template <typename InitFunc, typename BenchFunc>
+static void run_benchmarks(int size, int loops, int max_matches,
+ bool is_reverse, MicroBenchmark &bench,
+ InitFunc &&init, BenchFunc &&func) {
init(bench);
- double total_sec = 0.0;
+ double total_sec = 0.0;
u64a total_size = 0;
double bw = 0.0;
double avg_bw = 0.0;
double avg_time = 0.0;
if (max_matches) {
int pos = 0;
- for(int j = 0; j < max_matches - 1; j++) {
+ for (int j = 0; j < max_matches - 1; j++) {
bench.buf[pos] = 'b';
- pos = (j+1) *size / max_matches ;
+ pos = (j + 1) * size / max_matches;
bench.buf[pos] = 'a';
u64a actual_size = 0;
auto start = std::chrono::steady_clock::now();
- for(int i = 0; i < loops; i++) {
+ for (int i = 0; i < loops; i++) {
const u8 *res = func(bench);
- if (is_reverse)
- actual_size += bench.buf.data() + size - res;
- else
- actual_size += res - bench.buf.data();
+ if (is_reverse)
+ actual_size += bench.buf.data() + size - res;
+ else
+ actual_size += res - bench.buf.data();
}
auto end = std::chrono::steady_clock::now();
- double dt = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
+ double dt = std::chrono::duration_cast<std::chrono::microseconds>(
+ end - start)
+ .count();
total_sec += dt;
/*convert microseconds to seconds*/
/*calculate bandwidth*/
- bw = (actual_size / dt) * 1000000.0 / 1048576.0;
- /*std::cout << "act_size = " << act_size << std::endl;
- std::cout << "dt = " << dt << std::endl;
- std::cout << "bw = " << bw << std::endl;*/
- avg_bw += bw;
+ bw = (actual_size / dt) * 1000000.0 / 1048576.0;
+ /*std::cout << "act_size = " << act_size << std::endl;
+ std::cout << "dt = " << dt << std::endl;
+ std::cout << "bw = " << bw << std::endl;*/
+ avg_bw += bw;
/*convert to MB/s*/
max_bw = std::max(bw, max_bw);
/*calculate average time*/
}
avg_time /= max_matches;
avg_bw /= max_matches;
- total_sec /= 1000000.0;
+ total_sec /= 1000000.0;
/*convert average time to us*/
- printf(KMAG "%s: %u matches, %u * %u iterations," KBLU " total elapsed time =" RST " %.3f s, "
- KBLU "average time per call =" RST " %.3f μs," KBLU " max bandwidth = " RST " %.3f MB/s," KBLU " average bandwidth =" RST " %.3f MB/s \n",
- bench.label, max_matches, size ,loops, total_sec, avg_time, max_bw, avg_bw);
+ /* Keeping the color output
+ printf(KMAG "%s: %u matches, %u * %u iterations," KBLU
+ " total elapsed time =" RST " %.3f s, " KBLU
+ "average time per call =" RST " %.3f μs," KBLU
+ " max bandwidth = " RST " %.3f MB/s," KBLU
+ " average bandwidth =" RST " %.3f MB/s \n",
+ bench.label, max_matches, size, loops, total_sec, avg_time,
+ max_bw, avg_bw);
+ */
+ printf("%s,%u,%u,%u,%.3f,%.3f,%.3f,%.3f\n", bench.label, max_matches,
+ size, loops, total_sec, avg_time, max_bw, avg_bw);
} else {
auto start = std::chrono::steady_clock::now();
for (int i = 0; i < loops; i++) {
const u8 *res = func(bench);
}
auto end = std::chrono::steady_clock::now();
- total_sec += std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
+ total_sec +=
+ std::chrono::duration_cast<std::chrono::microseconds>(end - start)
+ .count();
/*calculate transferred size*/
total_size = size * loops;
/*calculate average time*/
max_bw = total_size / total_sec;
/*convert to MB/s*/
max_bw /= 1048576.0;
- printf(KMAG "%s: no matches, %u * %u iterations," KBLU " total elapsed time =" RST " %.3f s, "
- KBLU "average time per call =" RST " %.3f μs ," KBLU " bandwidth = " RST " %.3f MB/s \n",
- bench.label, size ,loops, total_sec, avg_time, max_bw );
+ /*Keeping the color output
+ printf(KMAG "%s: no matches, %u * %u iterations," KBLU " total elapsed
+ time =" RST " %.3f s, " KBLU "average time per call =" RST " %.3f μs ,"
+ KBLU " bandwidth = " RST " %.3f MB/s \n", bench.label, size ,loops,
+ total_sec, avg_time, max_bw );
+ */
+ printf("%s,0,%u,%u,%.3f,%.3f,%.3f,0\n", bench.label, size, loops,
+ total_sec, avg_time, max_bw);
}
}
-int main(){
+int main() {
int matches[] = {0, MAX_MATCHES};
std::vector<size_t> sizes;
- for (size_t i = 0; i < N; i++) sizes.push_back(16000 << i*2);
- const char charset[] = "aAaAaAaAAAaaaaAAAAaaaaAAAAAAaaaAAaaa";
-
+ for (size_t i = 0; i < N; i++)
+ sizes.push_back(16000 << i * 2);
+ const char charset[] = "aAaAaAaAAAaaaaAAAAaaaaAAAAAAaaaAAaaa";
+ printf("Bench Label, max_matches, size,loops, total_sec, avg_time, "
+ "max_bw, avg_bw\n");
for (int m = 0; m < 2; m++) {
for (size_t i = 0; i < std::size(sizes); i++) {
MicroBenchmark bench("Shufti", sizes[i]);
- run_benchmarks(sizes[i], MAX_LOOPS / sizes[i], matches[m], false, bench,
+ run_benchmarks(
+ sizes[i], MAX_LOOPS / sizes[i], matches[m], false, bench,
[&](MicroBenchmark &b) {
b.chars.set('a');
ue2::shuftiBuildMasks(b.chars, (u8 *)&b.lo, (u8 *)&b.hi);
memset(b.buf.data(), 'b', b.size);
},
[&](MicroBenchmark &b) {
- return shuftiExec(b.lo, b.hi, b.buf.data(), b.buf.data() + b.size);
- }
- );
+ return shuftiExec(b.lo, b.hi, b.buf.data(),
+ b.buf.data() + b.size);
+ });
}
for (size_t i = 0; i < std::size(sizes); i++) {
MicroBenchmark bench("Reverse Shufti", sizes[i]);
- run_benchmarks(sizes[i], MAX_LOOPS / sizes[i], matches[m], true, bench,
+ run_benchmarks(
+ sizes[i], MAX_LOOPS / sizes[i], matches[m], true, bench,
[&](MicroBenchmark &b) {
b.chars.set('a');
ue2::shuftiBuildMasks(b.chars, (u8 *)&b.lo, (u8 *)&b.hi);
memset(b.buf.data(), 'b', b.size);
},
[&](MicroBenchmark &b) {
- return rshuftiExec(b.lo, b.hi, b.buf.data(), b.buf.data() + b.size);
- }
- );
+ return rshuftiExec(b.lo, b.hi, b.buf.data(),
+ b.buf.data() + b.size);
+ });
}
for (size_t i = 0; i < std::size(sizes); i++) {
MicroBenchmark bench("Truffle", sizes[i]);
- run_benchmarks(sizes[i], MAX_LOOPS / sizes[i], matches[m], false, bench,
+ run_benchmarks(
+ sizes[i], MAX_LOOPS / sizes[i], matches[m], false, bench,
[&](MicroBenchmark &b) {
b.chars.set('a');
ue2::truffleBuildMasks(b.chars, (u8 *)&b.lo, (u8 *)&b.hi);
memset(b.buf.data(), 'b', b.size);
},
[&](MicroBenchmark &b) {
- return truffleExec(b.lo, b.hi, b.buf.data(), b.buf.data() + b.size);
- }
- );
+ return truffleExec(b.lo, b.hi, b.buf.data(),
+ b.buf.data() + b.size);
+ });
}
for (size_t i = 0; i < std::size(sizes); i++) {
MicroBenchmark bench("Reverse Truffle", sizes[i]);
- run_benchmarks(sizes[i], MAX_LOOPS / sizes[i], matches[m], true, bench,
+ run_benchmarks(
+ sizes[i], MAX_LOOPS / sizes[i], matches[m], true, bench,
[&](MicroBenchmark &b) {
b.chars.set('a');
ue2::truffleBuildMasks(b.chars, (u8 *)&b.lo, (u8 *)&b.hi);
memset(b.buf.data(), 'b', b.size);
},
[&](MicroBenchmark &b) {
- return rtruffleExec(b.lo, b.hi, b.buf.data(), b.buf.data() + b.size);
- }
- );
+ return rtruffleExec(b.lo, b.hi, b.buf.data(),
+ b.buf.data() + b.size);
+ });
}
for (size_t i = 0; i < std::size(sizes); i++) {
MicroBenchmark bench("Vermicelli", sizes[i]);
- run_benchmarks(sizes[i], MAX_LOOPS / sizes[i], matches[m], false, bench,
+ run_benchmarks(
+ sizes[i], MAX_LOOPS / sizes[i], matches[m], false, bench,
[&](MicroBenchmark &b) {
b.chars.set('a');
ue2::truffleBuildMasks(b.chars, (u8 *)&b.lo, (u8 *)&b.hi);
memset(b.buf.data(), 'b', b.size);
},
[&](MicroBenchmark &b) {
- return vermicelliExec('a', 'b', b.buf.data(), b.buf.data() + b.size);
- }
- );
+ return vermicelliExec('a', 'b', b.buf.data(),
+ b.buf.data() + b.size);
+ });
}
for (size_t i = 0; i < std::size(sizes); i++) {
MicroBenchmark bench("Reverse Vermicelli", sizes[i]);
- run_benchmarks(sizes[i], MAX_LOOPS / sizes[i], matches[m], true, bench,
+ run_benchmarks(
+ sizes[i], MAX_LOOPS / sizes[i], matches[m], true, bench,
[&](MicroBenchmark &b) {
b.chars.set('a');
ue2::truffleBuildMasks(b.chars, (u8 *)&b.lo, (u8 *)&b.hi);
memset(b.buf.data(), 'b', b.size);
},
[&](MicroBenchmark &b) {
- return rvermicelliExec('a', 'b', b.buf.data(), b.buf.data() + b.size);
- }
- );
+ return rvermicelliExec('a', 'b', b.buf.data(),
+ b.buf.data() + b.size);
+ });
}
for (size_t i = 0; i < std::size(sizes); i++) {
- //we imitate the noodle unit tests
+ // we imitate the noodle unit tests
std::string str;
const size_t char_len = 5;
str.resize(char_len + 1);
- for (size_t j=0; j < char_len; j++) {
- srand (time(NULL));
- int key = rand() % + 36 ;
+ for (size_t j = 0; j < char_len; j++) {
+ srand(time(NULL));
+ int key = rand() % +36;
str[char_len] = charset[key];
str[char_len + 1] = '\0';
}
MicroBenchmark bench("Noodle", sizes[i]);
- run_benchmarks(sizes[i], MAX_LOOPS / sizes[i], matches[m], false, bench,
+ run_benchmarks(
+ sizes[i], MAX_LOOPS / sizes[i], matches[m], false, bench,
[&](MicroBenchmark &b) {
ctxt.clear();
memset(b.buf.data(), 'a', b.size);
assert(b.nt != nullptr);
},
[&](MicroBenchmark &b) {
- noodExec(b.nt.get(), b.buf.data(), b.size, 0, hlmSimpleCallback, &b.scratch);
+ noodExec(b.nt.get(), b.buf.data(), b.size, 0,
+ hlmSimpleCallback, &b.scratch);
return b.buf.data() + b.size;
- }
- );
+ });
}
}