-
Notifications
You must be signed in to change notification settings - Fork 40
/
unittests.cpp
99 lines (80 loc) · 2.41 KB
/
unittests.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "all.h"
class UnitTests {
static const size_t size = 1024 * 32;
uint8_t array[size];
uint8_t byte;
struct Failed {};
public:
bool run() {
byte = 42;
try {
case1();
case2();
case3();
case4();
puts("All OK");
return true;
} catch (Failed&) {
return false;
}
}
private:
void case1() {
memset(array, 0, size);
test();
}
void case2() {
memset(array, -1, size);
test();
}
void case3() {
memset(array, byte, size);
test();
}
void case4() {
srand(0);
memset(array, 0, size);
for (size_t i=0; i < size; i++) {
if (rand() % 4 == 0)
array[i] = byte;
}
test();
}
void test() {
const uint64_t reference = scalar_count_bytes((const uint8_t*)array, size, byte);
#ifdef HAVE_SSE
test("SSE", sse_count_byte, reference);
test("SSE (popcount)", sse_count_byte_popcount, reference);
#endif
#ifdef HAVE_AVX2
test("AVX2", avx2_count_byte, reference);
//test("AVX2 (popcount)", avx2_count_byte_popcount, reference);
#endif
#ifdef HAVE_AVX512BW
test("AVX512", avx512bw_count_bytes, reference);
test("AVX512 (unrolled 4x)", avx512bw_count_bytes_unrolled, reference);
test("AVX512 (ver 2)", avx512bw_count_bytes__version2, reference);
test("AVX512 (ver 3)", avx512bw_count_bytes__version3, reference);
test("AVX512 (ver 4)", avx512bw_count_bytes__version4, reference);
test("AVX512 (ver 5)", avx512bw_count_bytes__version5, reference);
test("AVX512 (ver 5 unrolled 2x)", avx512bw_count_bytes__version5_unrolled2, reference);
test("AVX512 (ver 5 unrolled 4x)", avx512bw_count_bytes__version5_unrolled4, reference);
test("AVX512 (ver 6 unrolled 4x)", avx512bw_count_bytes__version6_unrolled4, reference);
#endif
}
template <typename FUNCTION>
void test(const char* name, FUNCTION fun, uint64_t reference) {
const uint64_t result = fun(array, size, byte);
if (result != reference) {
printf("%s failed: reference = %lu result = %lu\n", name, reference, result);
throw Failed{};
}
}
};
int main() {
UnitTests tests;
tests.run();
}