-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.cpp
123 lines (110 loc) · 4.33 KB
/
main.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <iostream>
#include <chrono>
#include "tbb/tbb.h"
using namespace std;
#include "Tree.h"
void loadKey(TID tid, Key &key) {
// Store the key of the tuple into the key vector
// Implementation is database specific
key.setKeyLen(sizeof(tid));
reinterpret_cast<uint64_t *>(&key[0])[0] = __builtin_bswap64(tid);
}
void multithreaded(char **argv) {
// std::cout << "multi threaded:" << std::endl;
uint64_t n = std::atoll(argv[1]);
uint64_t *keys = new uint64_t[n];
// Generate keys
for (uint64_t i = 0; i < n; i++)
// dense, sorted
keys[i] = i + 1;
if (atoi(argv[2]) == 1)
// dense, random
std::random_shuffle(keys, keys + n);
if (atoi(argv[2]) == 2)
// "pseudo-sparse" (the most-significant leaf bit gets lost)
for (uint64_t i = 0; i < n; i++)
keys[i] = (static_cast<uint64_t>(rand()) << 32) | static_cast<uint64_t>(rand());
// printf("operation,n,ops/s\n");
ART_OLC::Tree tree(loadKey);
//ART_ROWEX::Tree tree(loadKey);
const int THREAD_NUM=1;
// Build tree
{
auto starttime = std::chrono::system_clock::now();
// tbb::task_scheduler_init init(4);
tbb::task_arena arena(THREAD_NUM);
arena.execute([&] {
struct bitmask* cpuset = numa_allocate_cpumask();
numa_bitmask_setbit(cpuset, atoi(argv[3]));
numa_bind(cpuset);
numa_bitmask_free(cpuset);
tbb::parallel_for(tbb::blocked_range<uint64_t>(0, n), [&](const tbb::blocked_range<uint64_t> &range) {
auto t = tree.getThreadInfo();
for (uint64_t i = range.begin(); i != range.end(); i++) {
Key key;
loadKey(keys[i], key);
tree.insert(key, keys[i], t);
}
});
});
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::system_clock::now() - starttime);
printf("insert,%ld,%f\n", n, (n * 1.0) / duration.count());
}
{
// Lookup
auto starttime = std::chrono::system_clock::now();
tbb::task_arena arena(THREAD_NUM);
arena.execute([&] {
struct bitmask* cpuset = numa_allocate_cpumask();
numa_bitmask_setbit(cpuset, atoi(argv[3]));
numa_bind(cpuset);
numa_bitmask_free(cpuset);
tbb::parallel_for(tbb::blocked_range<uint64_t>(0, n), [&](const tbb::blocked_range<uint64_t> &range) {
auto t = tree.getThreadInfo();
for (uint64_t i = range.begin(); i != range.end(); i++) {
Key key;
loadKey(keys[i], key);
auto val = tree.lookup(key, t);
if (val != keys[i]) {
std::cout << "wrong key read: " << val << " expected:" << keys[i] << std::endl;
throw;
}
}
});
});
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::system_clock::now() - starttime);
printf("lookup,%ld,%f\n", n, (n * 1.0) / duration.count());
}
{
auto starttime = std::chrono::system_clock::now();
tbb::task_arena arena(THREAD_NUM);
arena.execute([&] {
struct bitmask* cpuset = numa_allocate_cpumask();
numa_bitmask_setbit(cpuset, atoi(argv[3]));
numa_bind(cpuset);
numa_bitmask_free(cpuset);
tbb::parallel_for(tbb::blocked_range<uint64_t>(0, n), [&](const tbb::blocked_range<uint64_t> &range) {
auto t = tree.getThreadInfo();
for (uint64_t i = range.begin(); i != range.end(); i++) {
Key key;
loadKey(keys[i], key);
tree.remove(key, keys[i], t);
}
});
});
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::system_clock::now() - starttime);
printf("remove,%ld,%f\n", n, (n * 1.0) / duration.count());
}
delete[] keys;
}
int main(int argc, char **argv) {
// if (argc != 3) {
// printf("usage: %s n 0|1|2\nn: number of keys\n0: sorted keys\n1: dense keys\n2: sparse keys\n", argv[0]);
// return 1;
// }
multithreaded(argv);
return 0;
}