Skip to content

Use a sentinel for list iterators - #115

Open
pauldreik wants to merge 1 commit into
mainfrom
list-sentinel
Open

Use a sentinel for list iterators#115
pauldreik wants to merge 1 commit into
mainfrom
list-sentinel

Conversation

@pauldreik

Copy link
Copy Markdown
Owner

Summary

  • represent list links as a circular chain around an embedded, valueless sentinel
  • keep old end iterators current across insertion without a container tail pointer
  • preserve transferred element iterators across splice and move operations
  • reduce list iterators from two pointers to one
  • cover old-end behavior plus single, range, and whole-list splice traversal

Boost.Asio exposed the old representation when it retained an empty list end iterator, spliced in a recycled reactor node, and decremented the old iterator.

Validation

  • focused GCC 14 system and psychicstd list tests after the final rebase
  • focused strict-compatibility list tests after the final rebase
  • full 322-test in-tree GCC 14 suite
  • focused ASan and UBSan runs
  • 30-repetition compile-time comparison against main: no significant changes

Represent list links as a circular chain around an embedded, valueless
sentinel. End iterators now point to a stable node, so an iterator obtained
before insertion sees the current tail and transferred element iterators follow
the destination after splice or move.

This removes the per-iterator tail snapshot and cuts iterators from two pointers
to one. It also replaces null endpoint cases with ordinary link updates without
growing the container.

Boost.Asio exposed the old-end issue when it spliced a recycled reactor queue
node into an empty list and decremented the previously obtained end iterator.
@github-actions

Copy link
Copy Markdown

Compile-time performance diff

Compiler: g++ (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0.

Repetitions: 5 per configuration.

psychicstd compile time, main vs this PR (same runner). 🟢 faster · 🔴 slower · 🟡 within noise. A change is colored only when its bootstrap 95% CI excludes 0 and it clears ±5% / 3ms. vs system is this PR's speedup over system libstdc++, for context -- a regression is less alarming if psychicstd is still far ahead. Median system-time drift (noise proxy): 0.1%.

🔴 1 slower · 🟡 2 within noise.

benchmark main PR Δ (95% CI) vs system
iostream 75.5ms 79.7ms 🔴 +5.6% [+4.1, +7.1] 3.3x
🟡 2 benchmark(s) within noise
benchmark main PR Δ (95% CI) vs system
all-headers 209.1ms 212.1ms 🟡 +1.4% [-1.4, +4.6] 6.6x
wordcounter 177.7ms 178.9ms 🟡 +0.6% [-1.5, +4.3] 3.2x

Reproduce this on your machine: scripts/compare_compile_time_to_ref.py --reps 5 g++ origin/main

@github-actions

Copy link
Copy Markdown

eigen build-time diff (compile / run tests)

Compiler: c++ (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0.

Repetitions: 2 per configuration.

eigen build time with psychicstd, main vs this PR (same runner). 🟢 faster · 🔴 slower · 🟡 within noise. A change is colored only when its bootstrap 95% CI excludes 0 and it clears ±5% / 3ms. vs system is this PR's speedup over system libstdc++, for context -- a regression is less alarming if psychicstd is still far ahead. Median system-time drift (noise proxy): 2.6%.

No significant changes (🟡 2 within noise).

🟡 2 benchmark(s) within noise
benchmark main PR Δ (95% CI) vs system
compile 16759.3ms 16478.8ms 🟡 -1.7% [-4.4, +1.1] 1.7x
run tests 37.0ms 36.2ms 🟡 -2.3% [-3.6, -0.9] 1.3x

Reproduce this on your machine: scripts/compare_realworld_to_ref.py eigen --build-type debug --reps 2

@github-actions

Copy link
Copy Markdown

rdfind build-time diff (configure / compile / run tests)

Compiler: c++ (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0.

Repetitions: 5 per configuration.

rdfind build time with psychicstd, main vs this PR (same runner). 🟢 faster · 🔴 slower · 🟡 within noise. A change is colored only when its bootstrap 95% CI excludes 0 and it clears ±5% / 3ms. vs system is this PR's speedup over system libstdc++, for context -- a regression is less alarming if psychicstd is still far ahead. Median system-time drift (noise proxy): 0.9%.

No significant changes (🟡 3 within noise).

🟡 3 benchmark(s) within noise
benchmark main PR Δ (95% CI) vs system
compile 365.1ms 382.9ms 🟡 +4.9% [-20.7, +10.6] 3.9x
configure 1205.3ms 1221.9ms 🟡 +1.4% [-5.3, +66.1] 1.0x
run tests 1982.0ms 1843.0ms 🟡 -7.0% [-27.8, +27.6] 1.0x

Reproduce this on your machine: scripts/compare_realworld_to_ref.py rdfind --build-type debug --reps 5

@github-actions

Copy link
Copy Markdown

flatbuffers build-time diff (configure / compile / run tests)

Compiler: c++ (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0.

Repetitions: 1 per configuration.

flatbuffers build time with psychicstd, main vs this PR (same runner). 🟢 faster · 🔴 slower · 🟡 within noise. A change is colored only when its bootstrap 95% CI excludes 0 and it clears ±5% / 3ms. vs system is this PR's speedup over system libstdc++, for context -- a regression is less alarming if psychicstd is still far ahead. Median system-time drift (noise proxy): 72.9%.

No significant changes (🟡 3 within noise).

🟡 3 benchmark(s) within noise
benchmark main PR Δ (95% CI) vs system
compile 23767.6ms 23773.0ms 🟡 +0.0% 2.2x
configure 434.8ms 428.5ms 🟡 -1.4% 1.1x
run tests 85.4ms 85.4ms 🟡 -0.0% 1.2x

Reproduce this on your machine: scripts/compare_realworld_to_ref.py flatbuffers --build-type debug --reps 1

@github-actions

Copy link
Copy Markdown

fmt build-time diff (compile / run tests)

Compiler: c++ (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0.

Repetitions: 2 per configuration.

fmt build time with psychicstd, main vs this PR (same runner). 🟢 faster · 🔴 slower · 🟡 within noise. A change is colored only when its bootstrap 95% CI excludes 0 and it clears ±5% / 3ms. vs system is this PR's speedup over system libstdc++, for context -- a regression is less alarming if psychicstd is still far ahead. Median system-time drift (noise proxy): 20.1%.

No significant changes (🟡 2 within noise).

🟡 2 benchmark(s) within noise
benchmark main PR Δ (95% CI) vs system
compile 31064.7ms 31240.4ms 🟡 +0.6% [-0.6, +1.8] 1.6x
run tests 241.4ms 233.7ms 🟡 -3.2% [-9.1, +2.8] 1.7x

Reproduce this on your machine: scripts/compare_realworld_to_ref.py fmt --build-type debug --reps 2

@github-actions

Copy link
Copy Markdown

simdutf build-time diff (compile / run tests)

Compiler: c++ (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0.

Repetitions: 1 per configuration.

simdutf build time with psychicstd, main vs this PR (same runner). 🟢 faster · 🔴 slower · 🟡 within noise. A change is colored only when its bootstrap 95% CI excludes 0 and it clears ±5% / 3ms. vs system is this PR's speedup over system libstdc++, for context -- a regression is less alarming if psychicstd is still far ahead. Median system-time drift (noise proxy): 2.7%.

No significant changes (🟡 2 within noise).

🟡 2 benchmark(s) within noise
benchmark main PR Δ (95% CI) vs system
compile 17901.2ms 18944.6ms 🟡 +5.8% 2.0x
run tests 40661.5ms 42226.6ms 🟡 +3.8% 1.0x

Reproduce this on your machine: scripts/compare_realworld_to_ref.py simdutf --build-type debug --reps 1

@github-actions

Copy link
Copy Markdown

catch2 build-time diff (compile / run tests)

Compiler: c++ (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0.

Repetitions: 3 per configuration.

catch2 build time with psychicstd, main vs this PR (same runner). 🟢 faster · 🔴 slower · 🟡 within noise. A change is colored only when its bootstrap 95% CI excludes 0 and it clears ±5% / 3ms. vs system is this PR's speedup over system libstdc++, for context -- a regression is less alarming if psychicstd is still far ahead. Median system-time drift (noise proxy): 0.1%.

No significant changes (🟡 2 within noise).

🟡 2 benchmark(s) within noise
benchmark main PR Δ (95% CI) vs system
compile 15219.9ms 15238.5ms 🟡 +0.1% [-0.4, +0.7] 3.6x
run tests 4088.0ms 4085.4ms 🟡 -0.1% [-2.4, +1.9] 0.9x

Reproduce this on your machine: scripts/compare_realworld_to_ref.py catch2 --build-type debug --reps 3

@github-actions

Copy link
Copy Markdown

Compliance diff

No changes detected.

72 header(s) unchanged
header passes/sampled
algorithm 10/40
any 9/18
array 27/40
atomic 16/40
bit 2/15
bitset 9/40
cassert 3/9
cctype 2/5
cerrno 5/29
cfloat 5/29
chrono 1/40
ciso646 5/29
climits 15/40
clocale 5/29
cmath 1/19
compare 5/14
complex 17/40
concepts 2/35
condition_variable 13/26
csetjmp 3/9
csignal 5/29
cstddef 13/21
cstdint 3/5
cstdio 5/29
cstdlib 3/9
cstring 2/5
ctime 5/29
cwchar 5/29
deque 29/40
exception 16/21
filesystem 3/40
forward_list 9/40
fstream 14/40
functional 17/40
initializer_list 0/0
iomanip 22/40
ios 13/40
iostream 0/2
istream 23/40
iterator 5/40
limits 36/37
list 6/40
locale 9/40
map 13/40
memory 15/40
mutex 15/40
new 19/40
numeric 4/40
optional 11/40
ostream 31/40
random 4/40
ranges 0/40
ratio 13/13
regex 3/40
set 1/40
sstream 7/40
stack 16/36
stdexcept 9/9
streambuf 30/37
string 2/40
string_view 15/40
system_error 30/40
thread 6/40
tuple 10/40
type_traits 21/40
typeinfo 2/5
unordered_map 15/40
unordered_set 12/40
utility 8/40
valarray 1/40
vector 29/40
version 0/40

Reproduce this on your machine: LLVM_ROOT=$PWD/llvm-project cp base_cache.json .compliance_cache.json && tools/compliance.py --recheck

@github-actions

Copy link
Copy Markdown

Sanitizer diff (ASan/UBSan)

No changes detected.

72 header(s) unchanged
header passes/sampled
algorithm 4/25
any 6/18
array 17/25
atomic 12/25
bit 2/15
bitset 3/25
cassert 3/9
cctype 2/5
cerrno 4/25
cfloat 4/25
chrono 0/25
ciso646 4/25
climits 11/25
clocale 4/25
cmath 1/19
compare 5/14
complex 11/25
concepts 2/25
condition_variable 13/25
csetjmp 3/9
csignal 4/25
cstddef 13/21
cstdint 3/5
cstdio 4/25
cstdlib 3/9
cstring 2/5
ctime 4/25
cwchar 4/25
deque 17/25
exception 16/21
filesystem 2/25
forward_list 6/25
fstream 8/25
functional 10/25
initializer_list 0/0
iomanip 13/25
ios 11/25
iostream 0/2
istream 10/25
iterator 4/25
limits 24/25
list 4/25
locale 6/25
map 7/25
memory 8/25
mutex 13/25
new 6/25
numeric 3/25
optional 8/25
ostream 18/25
random 3/25
ranges 0/25
ratio 13/13
regex 1/25
set 0/25
sstream 5/25
stack 9/25
stdexcept 9/9
streambuf 18/25
string 1/25
string_view 9/25
system_error 20/25
thread 5/25
tuple 7/25
type_traits 14/25
typeinfo 2/5
unordered_map 10/25
unordered_set 7/25
utility 6/25
valarray 0/25
vector 18/25
version 0/25

Reproduce this on your machine: LLVM_ROOT=$PWD/llvm-project cp sanitize_base_cache.json .compliance_cache.sanitize.json && tools/compliance.py --sanitize --recheck

@github-actions

Copy link
Copy Markdown

cppcheck build-time diff (compile)

Compiler: c++ (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0.

Repetitions: 2 per configuration.

cppcheck build time with psychicstd, main vs this PR (same runner). 🟢 faster · 🔴 slower · 🟡 within noise. A change is colored only when its bootstrap 95% CI excludes 0 and it clears ±5% / 3ms. vs system is this PR's speedup over system libstdc++, for context -- a regression is less alarming if psychicstd is still far ahead. Median system-time drift (noise proxy): 0.3%.

No significant changes (🟡 1 within noise).

🟡 1 benchmark(s) within noise
benchmark main PR Δ (95% CI) vs system
compile 48305.2ms 48693.4ms 🟡 +0.8% [+0.3, +1.3] 2.0x

Reproduce this on your machine: scripts/compare_realworld_to_ref.py cppcheck --build-type debug --reps 2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant