Skip to content

Commit 28c0b3e

Browse files
authored
Add key-value sort for 64-bit data
key-value represented in two separate std::vectors. Value is of type uint64_t.
1 parent 9f926ff commit 28c0b3e

13 files changed

+1806
-411
lines changed

.gitignore

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Prerequisites
2+
*.d
3+
4+
# Compiled Object files
5+
*.slo
6+
*.lo
7+
*.o
8+
*.obj
9+
10+
# Precompiled Headers
11+
*.gch
12+
*.pch
13+
14+
# Compiled Dynamic libraries
15+
*.so
16+
*.dylib
17+
*.dll
18+
19+
# Fortran module files
20+
*.mod
21+
*.smod
22+
23+
# Compiled Static libraries
24+
*.lai
25+
*.la
26+
*.a
27+
*.lib
28+
29+
# Executables
30+
*.exe
31+
*.out
32+
*.app
33+
34+
**/.vscode
35+

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ bench: $(BENCHDIR)/main.cpp $(SRCS)
2323
$(CXX) $(BENCHDIR)/main.cpp $(CXXFLAGS) -march=icelake-client -O3 -o benchexe
2424

2525
clean:
26-
rm -f $(TESTDIR)/*.o testexe benchexe
26+
rm -f $(TESTDIR)/*.o testexe benchexe

benchmarks/bench-tgl.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@
2525
| uniform random | int16_t | 10000 | 84703 | 1547726 | 18.3 |
2626
| uniform random | int16_t | 100000 | 1442726 | 19705242 | 13.7 |
2727
| uniform random | int16_t | 1000000 | 20210224 | 212137465 | 10.5 |
28-
|-----------------+-------------+------------+-----------------+-----------+----------|
28+
|-----------------+-------------+------------+-----------------+-----------+----------|

benchmarks/bench.hpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,19 @@
55

66
#include "avx512-16bit-qsort.hpp"
77
#include "avx512-32bit-qsort.hpp"
8+
#include "avx512-64bit-keyvaluesort.hpp"
89
#include "avx512-64bit-qsort.hpp"
910
#include <iostream>
1011
#include <numeric>
1112
#include <tuple>
1213
#include <vector>
1314

15+
template <typename K, typename V>
16+
struct sorted_t {
17+
K key;
18+
V value;
19+
};
20+
1421
static inline uint64_t cycles_start(void)
1522
{
1623
unsigned a, d;
@@ -72,3 +79,50 @@ std::tuple<uint64_t, uint64_t> bench_sort(const std::vector<T> arr,
7279
/ lastfew;
7380
return std::make_tuple(avx_sort, std_sort);
7481
}
82+
83+
template <typename K, typename V = uint64_t>
84+
std::tuple<uint64_t, uint64_t>
85+
bench_sort_kv(const std::vector<K> keys,
86+
const std::vector<V> values,
87+
const std::vector<sorted_t<K, V>> sortedaar,
88+
const uint64_t iters,
89+
const uint64_t lastfew)
90+
{
91+
92+
std::vector<K> keys_bckup = keys;
93+
std::vector<V> values_bckup = values;
94+
std::vector<sorted_t<K, V>> sortedaar_bckup = sortedaar;
95+
96+
std::vector<uint64_t> runtimes1, runtimes2;
97+
uint64_t start(0), end(0);
98+
for (uint64_t ii = 0; ii < iters; ++ii) {
99+
start = cycles_start();
100+
avx512_qsort_kv<K>(
101+
keys_bckup.data(), values_bckup.data(), keys_bckup.size());
102+
end = cycles_end();
103+
runtimes1.emplace_back(end - start);
104+
keys_bckup = keys;
105+
values_bckup = values;
106+
}
107+
uint64_t avx_sort = std::accumulate(runtimes1.end() - lastfew,
108+
runtimes1.end(),
109+
(uint64_t)0)
110+
/ lastfew;
111+
112+
for (uint64_t ii = 0; ii < iters; ++ii) {
113+
start = cycles_start();
114+
std::sort(sortedaar_bckup.begin(),
115+
sortedaar_bckup.end(),
116+
[](sorted_t<K, V> a, sorted_t<K, V> b) {
117+
return a.key < b.key;
118+
});
119+
end = cycles_end();
120+
runtimes2.emplace_back(end - start);
121+
sortedaar_bckup = sortedaar;
122+
}
123+
uint64_t std_sort = std::accumulate(runtimes2.end() - lastfew,
124+
runtimes2.end(),
125+
(uint64_t)0)
126+
/ lastfew;
127+
return std::make_tuple(avx_sort, std_sort);
128+
}

benchmarks/main.cpp

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ template <typename T1,
2222
void printLine(const char fill, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
2323
{
2424
std::cout << std::left << std::setw(3) << std::setfill(fill) << " | ";
25-
std::cout << std::left << std::setw(15) << std::setfill(fill) << t1
25+
std::cout << std::left << std::setw(18) << std::setfill(fill) << t1
2626
<< " | ";
2727
std::cout << std::left << std::setw(13) << std::setfill(fill) << t2
2828
<< " | ";
@@ -82,6 +82,60 @@ void run_bench(const std::string datatype)
8282
std::cout << std::setprecision(ss);
8383
}
8484

85+
template <typename K, typename V = uint64_t>
86+
void run_bench_kv(const std::string datatype)
87+
{
88+
std::streamsize ss = std::cout.precision();
89+
std::cout << std::fixed;
90+
std::cout << std::setprecision(1);
91+
std::vector<int> array_sizes = {10000, 100000, 1000000};
92+
for (auto size : array_sizes) {
93+
std::vector<K> keys;
94+
std::vector<V> values;
95+
std::vector<sorted_t<K, V>> sortedarr;
96+
97+
if (datatype.find("kv_uniform") != std::string::npos) {
98+
keys = get_uniform_rand_array<K>(size);
99+
}
100+
else if (datatype.find("kv_reverse") != std::string::npos) {
101+
for (int ii = 0; ii < size; ++ii) {
102+
//arr.emplace_back((T)(size - ii));
103+
keys.emplace_back((K)(size - ii));
104+
}
105+
}
106+
else if (datatype.find("kv_ordered") != std::string::npos) {
107+
for (int ii = 0; ii < size; ++ii) {
108+
keys.emplace_back((ii));
109+
}
110+
}
111+
else if (datatype.find("kv_limited") != std::string::npos) {
112+
keys = get_uniform_rand_array<K>(size, (K)10, (K)0);
113+
}
114+
else {
115+
std::cout << "Skipping unrecognized array type: " << datatype
116+
<< std::endl;
117+
return;
118+
}
119+
values = get_uniform_rand_array<V>(size);
120+
for (size_t i = 0; i < keys.size(); i++) {
121+
sorted_t<K, V> tmp_s;
122+
tmp_s.key = keys[i];
123+
tmp_s.value = values[i];
124+
sortedarr.emplace_back(tmp_s);
125+
}
126+
127+
auto out = bench_sort_kv(keys, values, sortedarr, 20, 10);
128+
printLine(' ',
129+
datatype,
130+
typeid(K).name(),
131+
sizeof(K),
132+
size,
133+
std::get<0>(out),
134+
std::get<1>(out),
135+
(float)std::get<1>(out) / std::get<0>(out));
136+
}
137+
std::cout << std::setprecision(ss);
138+
}
85139
void bench_all(const std::string datatype)
86140
{
87141
if (cpu_has_avx512bw()) {
@@ -97,7 +151,15 @@ void bench_all(const std::string datatype)
97151
}
98152
}
99153
}
154+
void bench_all_kv(const std::string datatype)
155+
{
156+
if (cpu_has_avx512bw()) {
100157

158+
run_bench_kv<uint64_t>(datatype);
159+
run_bench_kv<int64_t>(datatype);
160+
run_bench_kv<double>(datatype);
161+
}
162+
}
101163
int main(/*int argc, char *argv[]*/)
102164
{
103165
printLine(' ',
@@ -113,6 +175,11 @@ int main(/*int argc, char *argv[]*/)
113175
bench_all("reverse");
114176
bench_all("ordered");
115177
bench_all("limitedrange");
178+
179+
bench_all_kv("kv_uniform random");
180+
bench_all_kv("kv_reverse");
181+
bench_all_kv("kv_ordered");
182+
bench_all_kv("kv_limitedrange");
116183
printLine('-', "", "", "", "", "", "", "");
117184
return 0;
118185
}

0 commit comments

Comments
 (0)