Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f899e063b | ||
|
|
e5b9c03e77 | ||
|
|
a158d375f5 |
@@ -57,6 +57,7 @@ ConflictSet::ReadRange prefixRange(Arena &arena, TrivialSpan key) {
|
||||
|
||||
void benchConflictSet() {
|
||||
ankerl::nanobench::Bench bench;
|
||||
bench.minEpochIterations(10000);
|
||||
ConflictSet cs{0};
|
||||
|
||||
bench.batch(kOpsPerTx);
|
||||
|
||||
+2
-1
@@ -971,7 +971,8 @@ int getNodeIndex(Node3 *n, uint8_t index) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int getNodeIndexExists(Node3 *n, uint8_t index) {
|
||||
int getNodeIndexExists(Node3 *self, uint8_t index) {
|
||||
Node3 *n = (Node3 *)self;
|
||||
assume(n->numChildren >= 1);
|
||||
assume(n->numChildren <= 3);
|
||||
for (int i = 0; i < n->numChildren; ++i) {
|
||||
|
||||
@@ -4,7 +4,14 @@ Intended as an alternative to FoundationDB's skip list.
|
||||
|
||||
Hardware for all benchmarks is an AMD Ryzen 9 7900 with (2x32GB) 5600MT/s CL28-34-34-89 1.35V RAM.
|
||||
|
||||
Compiler is `Ubuntu clang version 20.0.0 (++20241029082144+7544d3af0e28-1~exp1~20241029082307.506)`.
|
||||
````
|
||||
$ clang++ --version
|
||||
|
||||
Ubuntu clang version 20.0.0 (++20241118082208+63b926af5ff4-1~exp1~20241118082226.549)
|
||||
Target: x86_64-pc-linux-gnu
|
||||
Thread model: posix
|
||||
InstalledDir: /usr/lib/llvm-20/bin
|
||||
```
|
||||
|
||||
# Microbenchmark
|
||||
|
||||
@@ -12,44 +19,45 @@ Compiler is `Ubuntu clang version 20.0.0 (++20241029082144+7544d3af0e28-1~exp1~2
|
||||
|
||||
| ns/op | op/s | err% | ins/op | cyc/op | IPC | bra/op | miss% | total | benchmark
|
||||
|--------------------:|--------------------:|--------:|----------------:|----------------:|-------:|---------------:|--------:|----------:|:----------
|
||||
| 159.65 | 6,263,576.52 | 1.6% | 2,972.36 | 820.37 | 3.623 | 504.59 | 0.0% | 0.01 | `point reads`
|
||||
| 156.32 | 6,397,320.65 | 0.7% | 2,913.62 | 806.87 | 3.611 | 490.19 | 0.0% | 0.01 | `prefix reads`
|
||||
| 229.18 | 4,363,293.65 | 1.2% | 3,541.05 | 1,219.75 | 2.903 | 629.33 | 0.0% | 0.01 | `range reads`
|
||||
| 363.37 | 2,752,026.30 | 0.3% | 5,273.63 | 1,951.54 | 2.702 | 851.66 | 1.7% | 0.01 | `point writes`
|
||||
| 364.99 | 2,739,787.02 | 0.3% | 5,250.92 | 1,958.54 | 2.681 | 839.24 | 1.7% | 0.01 | `prefix writes`
|
||||
| 242.26 | 4,127,796.58 | 2.9% | 3,117.33 | 1,304.41 | 2.390 | 541.07 | 2.8% | 0.02 | `range writes`
|
||||
| 562.48 | 1,777,855.27 | 0.8% | 7,305.21 | 3,034.34 | 2.408 | 1,329.30 | 1.3% | 0.01 | `monotonic increasing point writes`
|
||||
| 122,688.57 | 8,150.72 | 0.7% | 798,766.00 | 666,842.00 | 1.198 | 144,584.50 | 0.1% | 0.01 | `worst case for radix tree`
|
||||
| 41.71 | 23,976,459.34 | 1.7% | 885.00 | 219.17 | 4.038 | 132.00 | 0.0% | 0.01 | `create and destroy`
|
||||
| 163.82 | 6,104,214.81 | 0.0% | 3,014.03 | 823.99 | 3.658 | 504.59 | 0.0% | 1.96 | `point reads`
|
||||
| 160.65 | 6,224,551.06 | 0.0% | 2,954.16 | 808.03 | 3.656 | 490.17 | 0.0% | 1.92 | `prefix reads`
|
||||
| 243.07 | 4,114,000.62 | 0.0% | 3,592.41 | 1,224.77 | 2.933 | 629.31 | 0.0% | 2.90 | `range reads`
|
||||
| 454.64 | 2,199,540.91 | 0.1% | 4,450.57 | 2,297.43 | 1.937 | 707.92 | 2.1% | 5.43 | `point writes`
|
||||
| 451.41 | 2,215,265.93 | 0.0% | 4,410.22 | 2,281.37 | 1.933 | 694.74 | 2.1% | 5.39 | `prefix writes`
|
||||
| 302.92 | 3,301,213.43 | 0.0% | 2,315.38 | 1,530.92 | 1.512 | 396.69 | 3.3% | 3.60 | `range writes`
|
||||
| 470.36 | 2,126,014.73 | 1.0% | 6,999.33 | 2,457.12 | 2.849 | 1,251.74 | 1.3% | 0.06 | `monotonic increasing point writes`
|
||||
| 129,198.14 | 7,740.05 | 0.5% | 807,446.00 | 655,645.00 | 1.232 | 144,584.67 | 0.0% | 0.01 | `worst case for radix tree`
|
||||
| 46.34 | 21,578,562.58 | 0.7% | 902.00 | 232.26 | 3.884 | 132.00 | 0.0% | 0.01 | `create and destroy`
|
||||
|
||||
## Radix tree (this implementation)
|
||||
|
||||
|
||||
| ns/op | op/s | err% | ins/op | cyc/op | IPC | bra/op | miss% | total | benchmark
|
||||
|--------------------:|--------------------:|--------:|----------------:|----------------:|-------:|---------------:|--------:|----------:|:----------
|
||||
| 12.83 | 77,947,334.88 | 0.8% | 247.13 | 63.80 | 3.873 | 32.64 | 0.6% | 0.01 | `point reads`
|
||||
| 14.73 | 67,908,470.74 | 0.1% | 299.99 | 73.66 | 4.073 | 42.50 | 0.5% | 0.01 | `prefix reads`
|
||||
| 35.63 | 28,066,165.78 | 0.1% | 782.70 | 178.49 | 4.385 | 106.65 | 0.2% | 0.01 | `range reads`
|
||||
| 20.00 | 49,993,123.62 | 0.1% | 376.83 | 100.50 | 3.749 | 50.05 | 0.5% | 0.01 | `point writes`
|
||||
| 38.04 | 26,287,266.49 | 0.1% | 665.86 | 191.21 | 3.482 | 100.41 | 0.4% | 0.01 | `prefix writes`
|
||||
| 40.48 | 24,703,557.31 | 1.3% | 732.80 | 204.36 | 3.586 | 111.26 | 0.2% | 0.01 | `range writes`
|
||||
| 81.01 | 12,343,591.64 | 1.4% | 1,551.57 | 409.23 | 3.791 | 292.66 | 0.1% | 0.01 | `monotonic increasing point writes`
|
||||
| 315,672.00 | 3,167.85 | 1.7% | 4,043,066.00 | 1,590,315.00 | 2.542 | 714,828.00 | 0.1% | 0.01 | `worst case for radix tree`
|
||||
| 114.81 | 8,710,164.86 | 0.7% | 2,178.00 | 578.69 | 3.764 | 345.00 | 0.0% | 0.01 | `create and destroy`
|
||||
| 13.00 | 76,916,274.88 | 0.1% | 247.13 | 65.16 | 3.793 | 32.64 | 0.8% | 0.16 | `point reads`
|
||||
| 15.03 | 66,535,609.26 | 0.1% | 299.99 | 75.25 | 3.987 | 42.50 | 0.5% | 0.18 | `prefix reads`
|
||||
| 35.65 | 28,054,245.19 | 0.0% | 782.70 | 178.41 | 4.387 | 106.65 | 0.2% | 0.43 | `range reads`
|
||||
| 20.79 | 48,099,317.88 | 0.4% | 376.04 | 104.10 | 3.612 | 49.97 | 0.7% | 0.25 | `point writes`
|
||||
| 45.17 | 22,137,997.58 | 0.0% | 666.07 | 227.27 | 2.931 | 101.33 | 0.3% | 0.54 | `prefix writes`
|
||||
| 40.35 | 24,784,682.32 | 0.0% | 732.33 | 202.46 | 3.617 | 111.64 | 0.1% | 0.49 | `range writes`
|
||||
| 79.04 | 12,651,349.21 | 2.4% | 1,462.61 | 399.37 | 3.662 | 279.17 | 0.1% | 0.01 | `monotonic increasing point writes`
|
||||
| 313,894.00 | 3,185.79 | 0.3% | 4,043,060.00 | 1,585,794.00 | 2.550 | 714,828.00 | 0.1% | 0.01 | `worst case for radix tree`
|
||||
| 109.01 | 9,173,544.09 | 0.5% | 2,046.00 | 547.40 | 3.738 | 329.00 | 0.0% | 0.01 | `create and destroy`
|
||||
|
||||
# "Real data" test
|
||||
|
||||
Point queries only, best of three runs. Gc ratio is the ratio of time spent doing garbage collection to time spent adding writes or doing garbage collection. Lower is better.
|
||||
Point queries only. Gc ratio is the ratio of time spent doing garbage collection to time spent adding writes or doing garbage collection. Lower is better.
|
||||
|
||||
## skip list
|
||||
|
||||
```
|
||||
Check: 4.39702 seconds, 370.83 MB/s, Add: 4.50025 seconds, 124.583 MB/s, Gc ratio: 29.1333%, Peak idle memory: 5.51852e+06
|
||||
Check: 4.65306 seconds, 362.382 MB/s, Add: 3.92107 seconds, 146.729 MB/s, Gc ratio: 33.6261%, Peak idle memory: 5.61007e+06
|
||||
```
|
||||
|
||||
## radix tree
|
||||
|
||||
```
|
||||
Check: 0.975666 seconds, 1728.24 MB/s, Add: 1.19751 seconds, 480.444 MB/s, Gc ratio: 36.8478%, Peak idle memory: 2.39447e+06
|
||||
Check: 1.02927 seconds, 1638.24 MB/s, Add: 1.33663 seconds, 430.436 MB/s, Gc ratio: 35.3609%, Peak idle memory: 2.32922e+06
|
||||
```
|
||||
|
||||
## hash table
|
||||
@@ -57,5 +65,6 @@ Check: 0.975666 seconds, 1728.24 MB/s, Add: 1.19751 seconds, 480.444 MB/s, Gc ra
|
||||
(The hash table implementation doesn't work on range queries, and its purpose is to provide an idea of how fast point queries can be)
|
||||
|
||||
```
|
||||
Check: 0.84256 seconds, 1935.23 MB/s, Add: 0.697204 seconds, 804.146 MB/s, Gc ratio: 35.4091%
|
||||
Check: 0.856661 seconds, 1968.32 MB/s, Add: 0.709563 seconds, 810.831 MB/s, Gc ratio: 35.0388%, Peak idle memory: 0
|
||||
```
|
||||
|
||||
|
||||
+3
-3
@@ -133,10 +133,10 @@ int main(int argc, const char **argv) {
|
||||
int metricsCount;
|
||||
cs.getMetricsV1(&metrics, &metricsCount);
|
||||
for (int i = 0; i < metricsCount; ++i) {
|
||||
printf("# HELP %s %s\n", metrics[i].name, metrics[i].help);
|
||||
printf("# TYPE %s %s\n", metrics[i].name,
|
||||
fprintf(stderr, "# HELP %s %s\n", metrics[i].name, metrics[i].help);
|
||||
fprintf(stderr, "# TYPE %s %s\n", metrics[i].name,
|
||||
metrics[i].type == metrics[i].Counter ? "counter" : "gauge");
|
||||
printf("%s %g\n", metrics[i].name, metrics[i].getValue());
|
||||
fprintf(stderr, "%s %g\n", metrics[i].name, metrics[i].getValue());
|
||||
}
|
||||
|
||||
printf("Check: %g seconds, %g MB/s, Add: %g seconds, %g MB/s, Gc ratio: "
|
||||
|
||||
Executable
+79
@@ -0,0 +1,79 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Disable frequency scaling
|
||||
for i in $(seq "$(nproc)") ; do sudo cat /sys/devices/system/cpu/cpu$((i-1))/cpufreq/scaling_max_freq | sudo tee /sys/devices/system/cpu/cpu$((i-1))/cpufreq/scaling_min_freq >/dev/null ; done
|
||||
|
||||
cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=clang++ -G Ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_CXX_FLAGS=-DNVALGRIND > /dev/null
|
||||
cmake --build build > /dev/null
|
||||
|
||||
cat << 'EOF'
|
||||
A data structure for optimistic concurrency control on ranges of bitwise-lexicographically-ordered keys.
|
||||
|
||||
Intended as an alternative to FoundationDB's skip list.
|
||||
|
||||
Hardware for all benchmarks is an AMD Ryzen 9 7900 with (2x32GB) 5600MT/s CL28-34-34-89 1.35V RAM.
|
||||
|
||||
````
|
||||
$ clang++ --version
|
||||
|
||||
EOF
|
||||
|
||||
clang++ --version
|
||||
|
||||
cat << 'EOF'
|
||||
```
|
||||
|
||||
# Microbenchmark
|
||||
|
||||
## Skip list
|
||||
EOF
|
||||
|
||||
LD_LIBRARY_PATH=build/skip_list build/conflict_set_bench
|
||||
|
||||
cat << 'EOF'
|
||||
|
||||
## Radix tree (this implementation)
|
||||
|
||||
EOF
|
||||
|
||||
LD_LIBRARY_PATH=build/radix_tree build/conflict_set_bench
|
||||
|
||||
cat << 'EOF'
|
||||
|
||||
# "Real data" test
|
||||
|
||||
Point queries only. Gc ratio is the ratio of time spent doing garbage collection to time spent adding writes or doing garbage collection. Lower is better.
|
||||
|
||||
## skip list
|
||||
|
||||
```
|
||||
EOF
|
||||
|
||||
LD_LIBRARY_PATH=build/skip_list build/real_data_bench ~/Downloads/quotes_2008-08.txt
|
||||
|
||||
cat << 'EOF'
|
||||
```
|
||||
|
||||
## radix tree
|
||||
|
||||
```
|
||||
EOF
|
||||
|
||||
LD_LIBRARY_PATH=build/radix_tree build/real_data_bench ~/Downloads/quotes_2008-08.txt
|
||||
|
||||
cat << 'EOF'
|
||||
```
|
||||
|
||||
## hash table
|
||||
|
||||
(The hash table implementation doesn't work on range queries, and its purpose is to provide an idea of how fast point queries can be)
|
||||
|
||||
```
|
||||
EOF
|
||||
|
||||
LD_LIBRARY_PATH=build/hash_table build/real_data_bench ~/Downloads/quotes_2008-08.txt
|
||||
|
||||
cat << 'EOF'
|
||||
```
|
||||
|
||||
EOF
|
||||
Reference in New Issue
Block a user