-
Notifications
You must be signed in to change notification settings - Fork 59
/
bench-objsort.hpp
109 lines (100 loc) · 2.95 KB
/
bench-objsort.hpp
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
100
101
102
103
104
105
106
107
108
109
#include <cmath>
static constexpr char x[] = "x";
static constexpr char euclidean[] = "euclidean";
static constexpr char taxicab[] = "taxicab";
static constexpr char chebyshev[] = "chebyshev";
template <typename T, const char *val>
struct Point3D {
T x;
T y;
T z;
static constexpr std::string_view name {val};
Point3D()
{
x = (T)rand() / RAND_MAX;
y = (T)rand() / RAND_MAX;
z = (T)rand() / RAND_MAX;
}
T distance()
{
if constexpr (name == "x") { return x; }
else if constexpr (name == "euclidean") {
return std::sqrt(x * x + y * y + z * z);
}
else if constexpr (name == "taxicab") {
return std::abs(x) + std::abs(y) + std::abs(z);
}
else if constexpr (name == "chebyshev") {
return std::max(std::max(std::abs(x), std::abs(y)), std::abs(z));
}
}
};
template <typename T>
std::vector<T> init_data(const int size)
{
srand(42);
std::vector<T> arr;
for (auto ii = 0; ii < size; ++ii) {
T temp;
arr.push_back(temp);
}
return arr;
}
template <typename T>
struct less_than_key {
inline bool operator()(T &p1, T &p2)
{
return (p1.distance() < p2.distance());
}
};
template <typename T>
static void scalarobjsort(benchmark::State &state)
{
// set up array
std::vector<T> arr = init_data<T>(state.range(0));
std::vector<T> arr_bkp = arr;
// benchmark
for (auto _ : state) {
std::sort(arr.begin(), arr.end(), less_than_key<T>());
state.PauseTiming();
arr = arr_bkp;
state.ResumeTiming();
}
}
template <typename T>
static void simdobjsort(benchmark::State &state)
{
// set up array
std::vector<T> arr = init_data<T>(state.range(0));
std::vector<T> arr_bkp = arr;
// benchmark
for (auto _ : state) {
x86simdsort::object_qsort(
arr.data(), arr.size(), [](T p) { return p.distance(); });
state.PauseTiming();
if (!std::is_sorted(arr.begin(), arr.end(), less_than_key<T>())) {
std::cout << "sorting failed \n";
}
arr = arr_bkp;
state.ResumeTiming();
}
}
#define BENCHMARK_OBJSORT(func, T, type, dist) \
BENCHMARK_TEMPLATE(func, T<type, dist>) \
->Arg(10e1) \
->Arg(10e2) \
->Arg(10e3) \
->Arg(10e4) \
->Arg(10e5) \
->Arg(10e6);
#define BENCH_ALL(dtype) \
BENCHMARK_OBJSORT(simdobjsort, Point3D, dtype, x) \
BENCHMARK_OBJSORT(scalarobjsort, Point3D, dtype, x) \
BENCHMARK_OBJSORT(simdobjsort, Point3D, dtype, taxicab) \
BENCHMARK_OBJSORT(scalarobjsort, Point3D, dtype, taxicab) \
BENCHMARK_OBJSORT(simdobjsort, Point3D, dtype, euclidean) \
BENCHMARK_OBJSORT(scalarobjsort, Point3D, dtype, euclidean) \
BENCHMARK_OBJSORT(simdobjsort, Point3D, dtype, chebyshev) \
BENCHMARK_OBJSORT(scalarobjsort, Point3D, dtype, chebyshev)
BENCH_ALL(double)
BENCH_ALL(float)