Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HP with Optimistic Traversal #54

Merged
merged 84 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
7d1aa9c
Initial impl
Lee-Janggun Sep 8, 2024
203b711
Implement HList for HP.
Lee-Janggun Sep 9, 2024
cabf9b3
WIP
Lee-Janggun Sep 9, 2024
c51edf5
Fix a bug in HP HList
powergee Sep 10, 2024
a67bb16
Apply `Shared<T>` API for HP Lists
powergee Sep 10, 2024
46d5366
Cleanup impl
Lee-Janggun Sep 11, 2024
ffcbcb2
Cleanup
Lee-Janggun Sep 11, 2024
716c85d
Use optimized retire
Lee-Janggun Sep 11, 2024
f34c093
Remove an unused import (`retire`)
powergee Sep 11, 2024
c011a6e
Add a sanitizing script for HP
powergee Sep 11, 2024
e19c562
Implement HP HHSList
powergee Sep 12, 2024
35a36ad
Implement HHS-based Hashmap for HP
powergee Sep 12, 2024
cd0e7a5
Implement HP NMTree
powergee Sep 13, 2024
cecc5cc
Optimize hlist impl.
Lee-Janggun Sep 17, 2024
bc9da72
Add some comments.
Lee-Janggun Sep 19, 2024
8469da7
Fix a null reference bug in HP HList
powergee Sep 20, 2024
c39c4fa
Temporarily enlarge small bag sizes
powergee Sep 20, 2024
5f6d693
Refactor HP H(HS)List implementation
powergee Sep 20, 2024
8f9e176
Temporarily enlarge small bag sizes for HP++
powergee Sep 20, 2024
317d853
Refactor HP NMTree implementation
powergee Sep 20, 2024
7056a1c
Fix mistakes in HP(++) implementations that `handle.thread` and hazar…
powergee Sep 23, 2024
78e7cfb
Fix a linearizability bug in HP++ SkipList
powergee Sep 23, 2024
12a7b47
Implement HP SkipList with optimistic traversals
powergee Sep 23, 2024
f804f05
Add bag size configurations for major SMRs
powergee Sep 23, 2024
a6dd3ee
Ignore `__pycache__`
powergee Sep 25, 2024
1f7dac1
Use atomic operations to access the bag capacity
powergee Sep 25, 2024
55bb641
Fix race
Lee-Janggun Oct 3, 2024
4bb594b
Add bench scripts
powergee Oct 7, 2024
e750620
[WIP] implementing ElimABTree
powergee Oct 10, 2024
ba9872f
Fix bugs in prefilling of Bonsai Tree
powergee Oct 22, 2024
954c2c6
[WIP] Implement a draft version of EBR ElimABTree
powergee Oct 24, 2024
cbba802
Add `mask_light` and add some useful functionalities
powergee Oct 24, 2024
789e3d3
Minor code formatting
powergee Oct 24, 2024
d79a18b
Implement HP-(B)RCU Bonsai Trees
powergee Oct 24, 2024
e616549
Support returning an owned `V` in EBR-based DSs
powergee Oct 24, 2024
cc2203e
Register `ElimAbTree` as a runnable data structure
powergee Oct 24, 2024
634f613
Fix a typo in EBR ElimABTree
powergee Oct 24, 2024
af26a7d
Fix a bug in `fix_underfull_violation`
powergee Oct 25, 2024
f62c260
Remove redundant `InsertResult`
powergee Oct 25, 2024
b12cc7d
Make `weight` immutable
powergee Oct 25, 2024
eed9710
Clean up the implementation of ElimABTree
powergee Oct 25, 2024
fc2dcae
Revailidate the size of the node
powergee Oct 25, 2024
209c7ab
Add `try_acq_val_or` to reduce locking boilerplates
powergee Oct 28, 2024
b714f94
Make ElimAbTree more Rusty
powergee Oct 28, 2024
41f12a7
Make ElimAbTree more Rusty with iterators
powergee Oct 29, 2024
70b738a
Support returning an owned `V` in NR-based DSs
powergee Oct 29, 2024
8d07a2a
Implement NR ElimAbTree
powergee Oct 29, 2024
a4bd4c5
Support returning an owned `V` in HP(++)-based DSs
powergee Oct 29, 2024
1e929cb
Add NR ElimAbTree to the executable data structures
powergee Oct 29, 2024
5a621b2
Implement HP ElimAbTree
powergee Oct 29, 2024
cbd19b4
Make `V` customizable in `smoke` of (B)RCU
powergee Oct 29, 2024
cfc9150
Fix a bug in HP ElimAbTree
powergee Oct 30, 2024
336be6a
Implement HP-(B)RCU ElimAbTree
powergee Oct 30, 2024
0c28af5
Use `Release` orderings for marking in HP ElimAbTree
powergee Oct 30, 2024
80fbe7f
Update the bench script of HP-revisted
powergee Oct 30, 2024
bac2af2
Add ElimAbTree in the plot script
powergee Nov 1, 2024
490e30b
Fix a small typo error in `plot.py`
powergee Nov 1, 2024
327046f
Fix bugs in HP(++) HHSList
powergee Nov 1, 2024
e1cd974
Implement CrystallineL and its lists
powergee Nov 5, 2024
7cbb2b1
Reclaim thread-local bags during `Domain::drop`
powergee Nov 5, 2024
1cad22d
Implement CrystallineL HashMap
powergee Nov 5, 2024
a5a4d24
Revert removing `unsafe` from `clear_all`
powergee Nov 5, 2024
2d53087
Remove a redundant unsafe block
powergee Nov 6, 2024
b3682de
Add a caution of `clear_all` on each operation
powergee Nov 6, 2024
e136587
Implement CrystallineL NMTree
powergee Nov 6, 2024
fbf09af
Implement hazard eras
powergee Nov 6, 2024
22b04ff
Support returning an owned `V` in PEBR-based DSs
powergee Nov 7, 2024
0443df5
Make `V` customizable in `smoke` of PEBR
powergee Nov 7, 2024
e99c109
Implement PEBR ElimAbTree
powergee Nov 8, 2024
489f649
Initialize VBR objects by `Default`
powergee Nov 8, 2024
7a5a121
[WIP] Implementing VBR ElimAbTree (currently buggy)
powergee Nov 10, 2024
f167139
Fix a bug in VBR ElimAbTree (missing validation)
powergee Nov 10, 2024
c8645c2
Remove incorrect `debug_assert`s in HP SkipList
powergee Nov 10, 2024
2a5ea90
Revise `search_basic` implementation in HP ElimAbTree
powergee Nov 10, 2024
52b5964
Remove `run.sh` and add `+x` to all bash scripts
powergee Nov 10, 2024
d32eb24
Update bench scripts
powergee Nov 1, 2024
f176f0a
Update bench and plot scripts
powergee Nov 7, 2024
2e30fcb
Add PEBR- and VBR-based ElimAbTree
powergee Nov 11, 2024
0f54e91
Check if the key is `Some` in `child_index` of VBR ElimAbTree
powergee Nov 11, 2024
77dc68c
Add scripts for HP trees experiments
powergee Nov 11, 2024
1f6ad72
Replace "unreclaimed blocks" with "unreclaimed nodes"
powergee Nov 11, 2024
cb17389
Remove unused materials
powergee Nov 27, 2024
9c2dea2
Update README and add an experiment script
powergee Nov 27, 2024
7401573
Add execution permission for HP experiment script
powergee Nov 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ tags
*.pdf
*.csv
.python-version
__pycache__
21 changes: 11 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ csv = "1.3.0"
rand = "0.8"
typenum = "1.17"
num = "0.4.3"
arrayvec = "0.7.6"
scopeguard = "1"
hp_pp = { path = "./smrs/hp-pp" }
nbr = { path = "./smrs/nbr" }
cdrc = { path = "./smrs/cdrc" }
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ where
* `skip-list`: lock-free skiplist by Herlihy and Shavit, with wait-free get() for schemes other than HP \[3\]
* `bonsai-tree`: A non-blocking variant of Bonsai tree \[5\]
* `efrb-tree`: Ellen et al. ’s tree \[6\]
* `elim-ab-tree`: An (a,b) tree with elimination \[17\]
* Reclamation scheme
* `nr`: A baseline that does not reclaim memory
* `ebr`: Epoch-based RCU \[1,7\]
Expand Down Expand Up @@ -276,3 +277,4 @@ Note that sanitizer may report memory leaks when used against CIRC EBR. This is
* \[14\] Jeonghyeon Kim, Jaehwang Jung, and Jeehoon Kang. 2024. Expediting Hazard Pointers with Bounded RCU Critical Sections. In Proceedings of the 36th ACM Symposium on Parallelism in Algorithms and Architectures (SPAA 2024), June 17–21, 2024, Nantes, France. ACM, New York, NY, USA, 34 pages. <https://doi.org/10.1145/3626183.3659941>
* \[15\] Jaehwang Jung, Jeonghyeon Kim, Matthew J. Parkinson, and Jeehoon Kang. 2024. Concurrent Immediate Reference Counting. Proc. ACM Program. Lang. 8, PLDI, Article 153 (June 2024), 24 pages. <https://doi.org/10.1145/3656383>
* \[16\] Gali Sheffi, Maurice Herlihy, and Erez Petrank. 2021. VBR: Version Based Reclamation. In Proceedings of the 33rd ACM Symposium on Parallelism in Algorithms and Architectures (Virtual Event, USA) (SPAA ’21). Association for Computing Machinery, New York, NY, USA, 443–445. <https://doi.org/10.1145/3409964.3461817>
* \[17\] Anubhav Srivastava and Trevor Brown. 2022. Elimination (a,b)-trees with fast, durable updates. In Proceedings of the 27th ACM SIGPLAN Symposium on Principles and Practice of Parallel Programming (PPoPP '22). Association for Computing Machinery, New York, NY, USA, 416–430. <https://doi.org/10.1145/3503221.3508441>
99 changes: 99 additions & 0 deletions bench-scripts/hp-revisited/bench-hp-trees.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/usr/bin/env python

import subprocess
import os

RESULTS_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "results")
BIN_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "..", "target", "release")

dss = ['nm-tree', 'efrb-tree']
# "-large" suffix if it uses a large garbage bag.
mms = ['hp']
i = 10
cpu_count = os.cpu_count()
if not cpu_count or cpu_count <= 24:
ts = list(map(str, [1] + list(range(4, 33, 4))))
elif cpu_count <= 64:
ts = list(map(str, [1] + list(range(8, 129, 8))))
else:
ts = list(map(str, [1] + list(range(12, 193, 12))))
runs = 2
gs = [0, 1, 2]

subprocess.run(['cargo', 'build', '--release'])

def key_ranges(ds):
return ["100000"]

def is_suffix(orig, suf):
return len(suf) <= len(orig) and mm[-len(suf):] == suf

def make_cmd(mm, i, ds, g, t, kr):
bag = "small"
if is_suffix(mm, "-large"):
mm = mm[:len(mm)-len("-large")]
bag = "large"

return [os.path.join(BIN_PATH, mm),
'-i', str(i),
'-d', str(ds),
'-g', str(g),
'-t', str(t),
'-r', str(kr),
'-b', bag,
'-o', os.path.join(RESULTS_PATH, f'{ds}.csv')]

def invalid(mm, ds, g):
is_invalid = False
if ds == 'hhs-list':
is_invalid |= g == 0 # HHSList is just HList with faster get()
if mm == 'nbr':
is_invalid |= ds in ["hm-list", "skip-list"]
if ds == 'elim-ab-tree':
is_invalid |= mm in ["pebr", "hp-pp", "vbr"]
return is_invalid

cmds = []

for ds in dss:
for kr in key_ranges(ds):
for mm in mms:
for g in gs:
if invalid(mm, ds, g):
continue
for t in ts:
cmds.append(make_cmd(mm, i, ds, g, t, kr))

print('number of configurations: ', len(cmds))
print('estimated time: ', (len(cmds) * i * 1.1) // 60, ' min *', runs, 'times\n')

for i, cmd in enumerate(cmds):
try:
print(f"\rdry-running commands... ({i+1}/{len(cmds)})", end="")
subprocess.run(cmd + ['--dry-run'])
except:
print(f"A dry-run for the following command is failed:\n{' '.join(cmd)}")
exit(1)
print("\nAll dry-runs passed!\n")

os.makedirs(RESULTS_PATH, exist_ok=True)
failed = []
for run in range(runs):
for i, cmd in enumerate(cmds):
print("run {}/{}, bench {}/{}: '{}'".format(run + 1, runs, i + 1, len(cmds), ' '.join(cmd)))
try:
subprocess.run(cmd, timeout=i+30)
except subprocess.TimeoutExpired:
print("timeout")
failed.append(' '.join(cmd))
except KeyboardInterrupt:
if len(failed) > 0:
print("====failed====")
print("\n".join(failed))
exit(0)
except:
failed.append(' '.join(cmd))

if len(failed) > 0:
print("====failed====")
print("\n".join(failed))
99 changes: 99 additions & 0 deletions bench-scripts/hp-revisited/bench-short-lists.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/usr/bin/env python

import subprocess
import os

RESULTS_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "results")
BIN_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "..", "target", "release")

dss = ['hhs-list', 'hm-list']
# "-large" suffix if it uses a large garbage bag.
mms = ['hp', 'hp-pp']
i = 10
cpu_count = os.cpu_count()
if not cpu_count or cpu_count <= 24:
ts = list(map(str, [1] + list(range(4, 33, 4))))
elif cpu_count <= 64:
ts = list(map(str, [1] + list(range(8, 129, 8))))
else:
ts = list(map(str, [1] + list(range(12, 193, 12))))
runs = 2
gs = [0, 1, 2]

subprocess.run(['cargo', 'build', '--release'])

def key_ranges(ds):
return ["16"]

def is_suffix(orig, suf):
return len(suf) <= len(orig) and mm[-len(suf):] == suf

def make_cmd(mm, i, ds, g, t, kr):
bag = "small"
if is_suffix(mm, "-large"):
mm = mm[:len(mm)-len("-large")]
bag = "large"

return [os.path.join(BIN_PATH, mm),
'-i', str(i),
'-d', str(ds),
'-g', str(g),
'-t', str(t),
'-r', str(kr),
'-b', bag,
'-o', os.path.join(RESULTS_PATH, f'{ds}.csv')]

def invalid(mm, ds, g):
is_invalid = False
if ds == 'hhs-list':
is_invalid |= g == 0 # HHSList is just HList with faster get()
if mm == 'nbr':
is_invalid |= ds in ["hm-list", "skip-list"]
if ds == 'elim-ab-tree':
is_invalid |= mm in ["pebr", "hp-pp", "vbr"]
return is_invalid

cmds = []

for ds in dss:
for kr in key_ranges(ds):
for mm in mms:
for g in gs:
if invalid(mm, ds, g):
continue
for t in ts:
cmds.append(make_cmd(mm, i, ds, g, t, kr))

print('number of configurations: ', len(cmds))
print('estimated time: ', (len(cmds) * i * 1.1) // 60, ' min *', runs, 'times\n')

for i, cmd in enumerate(cmds):
try:
print(f"\rdry-running commands... ({i+1}/{len(cmds)})", end="")
subprocess.run(cmd + ['--dry-run'])
except:
print(f"A dry-run for the following command is failed:\n{' '.join(cmd)}")
exit(1)
print("\nAll dry-runs passed!\n")

os.makedirs(RESULTS_PATH, exist_ok=True)
failed = []
for run in range(runs):
for i, cmd in enumerate(cmds):
print("run {}/{}, bench {}/{}: '{}'".format(run + 1, runs, i + 1, len(cmds), ' '.join(cmd)))
try:
subprocess.run(cmd, timeout=i+30)
except subprocess.TimeoutExpired:
print("timeout")
failed.append(' '.join(cmd))
except KeyboardInterrupt:
if len(failed) > 0:
print("====failed====")
print("\n".join(failed))
exit(0)
except:
failed.append(' '.join(cmd))

if len(failed) > 0:
print("====failed====")
print("\n".join(failed))
Loading
Loading