Note, I've tried to use librseq, but looks like it does not worth it,
for read it may get up to 16%, while contended atomic vs uncontended is
30x.
Though rseq can also help with contention between write and read sides,
but it is also neglectible, it is only around 40ns win for p99+, while
complete read of all counters (for metric_log) is 2us vs 38us, yes, it
is 19x more, but it is still only 38us, and unlikely the contention is a
problem there.
v2: switch users to shared counter - 30x faster
v3: use NPROC over MAX_CPUs
v4: remove atomic pointer in ctor
v5: rename shard → per_cpu
v6: cache-line-align ProfileEvents per-CPU rows
v7: Add benchmark for ProfileEvents under 500 threads × 50 groups
v8: Drop librseq from ProfileEvents per-CPU sharding (does not give lots of benefit)
per-cpu atomic
==============
Benchmark Time CPU Iterations UserCounters...
---------------------------------------------------------------------------------------------------------
BM_ProfileEvents/1000/process_time/real_time 0.948 ms 26.1 ms 694 groups=50 incs/thread/step=1.44092 items_per_second=527.21M/s ns/inc=1.89678ns threads=500 users=1
BM_ProfileEvents/10000/process_time/real_time 5.13 ms 213 ms 110 groups=50 incs/thread/step=90.9091 items_per_second=975.257M/s ns/inc=1025.37ps threads=500 users=1
BM_ProfileEvents/100000/process_time/real_time 38.3 ms 1862 ms 18 groups=50 incs/thread/step=5.55556k items_per_second=1.30592G/s ns/inc=765.745ps threads=500 users=1
rseq
==============
Benchmark Time CPU Iterations UserCounters...
---------------------------------------------------------------------------------------------------------
BM_ProfileEvents/1000/process_time/real_time 0.875 ms 22.3 ms 753 groups=50 incs/thread/step=1.32802 items_per_second=571.651M/s ns/inc=1.74932ns threads=500 users=1
BM_ProfileEvents/10000/process_time/real_time 4.64 ms 175 ms 156 groups=50 incs/thread/step=64.1026 items_per_second=1076.95M/s ns/inc=928.552ps threads=500 users=1
BM_ProfileEvents/100000/process_time/real_time 34.6 ms 1576 ms 20 groups=50 incs/thread/step=5k items_per_second=1.44688G/s ns/inc=691.142ps threads=500 users=1
v9: Add user_profile_events_per_cpu server setting
v10: Cache-line-align the per-user ProfileEvents counter allocation
v11: Resolve sched_getcpu once per logical ProfileEvents increment
v12: More benchmarks