[libcxx-commits] [libcxx] [libc++] Optimizations for uniform_int_distribution (PR #140161)

via libcxx-commits libcxx-commits at lists.llvm.org
Mon Jun 23 18:08:27 PDT 2025


LRFLEW wrote:

I went ahead and updated the benchmark program. I had written the benchmark with this change in mind, which primarily focused on changes to `__independent_bits_engine`. As such, I only focused on cases that minimized rejected samples after the coercion to random bits. Since the topic of potentially changing the distribution algorithm was brought up, I figured I'd make the test a bit more general, also including worst-case and median-case tests for sample rejection. This helps make the test more generally useful if we end up using it to test alternative algorithms. For this PR, these new cases will show less improvement than the best-case tests (since the most significant optimization here results in a constant-time improvement), but still shows pretty good improvements for me on my machine.

The test cases work out like this, where `N` is the number of bits to be generated by `__independent_bits_engine`: `(1 << N)` is the best-case, resulting in no samples returned from `__independent_bits_engine` being rejected, `(1 << (N - 1)) + 1` is the worst-case, resulting in just under 50% of samples being rejected, and `(1 << (N - 1)) + (1 << (N - 2))` being the median case, with just under 25% of samples being rejected.

I was also able to get `libcxx-compare-benchmarks` working for me (I had problems with the part of the script that generated the venv, but I was able to get it working by disabling the venv part ofthe script entirely), so I can post my results from that on my machine:

```
$ libcxx/utils/libcxx-compare-benchmarks build/baseline build/uidibe libcxx/test/benchmarks/numeric/rand.uni.int.bench.cpp
Comparing build/baseline/libcxx/test/benchmarks/numeric/Output/rand.uni.int.bench.cpp.dir/benchmark-result.json to build/uidibe/libcxx/test/benchmarks/numeric/Output/rand.uni.int.bench.cpp.dir/benchmark-result.json
Benchmark                                                                                      Time             CPU      Time Old      Time New       CPU Old       CPU New
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
bm_uniform_int_distribution<std::minstd_rand0, 1ull << 20>                                  -0.7058         -0.7058            18             5            18             5
bm_uniform_int_distribution<std::ranlux24_base, 1ull << 20>                                 -0.4718         -0.4718            22            12            22            12
bm_uniform_int_distribution<std::minstd_rand0, (1ull << 19) + 1ull>                         -0.4173         -0.4173            28            16            28            16
bm_uniform_int_distribution<std::ranlux24_base, (1ull << 19) + 1ull>                        -0.3483         -0.3483            39            25            39            25
bm_uniform_int_distribution<std::minstd_rand0, (1ull << 19) + (1ull << 18)>                 -0.5493         -0.5493            21            10            21            10
bm_uniform_int_distribution<std::ranlux24_base, (1ull << 19) + (1ull << 18)>                -0.4406         -0.4406            28            15            28            15
bm_uniform_int_distribution<std::minstd_rand0, 1ull << 40>                                  -0.2927         -0.2927            19            14            19            14
bm_uniform_int_distribution<std::ranlux24_base, 1ull << 40>                                 -0.3309         -0.3309            29            19            29            19
bm_uniform_int_distribution<std::minstd_rand0, (1ull << 39) + 1ull>                         -0.1527         -0.1527            35            29            35            29
bm_uniform_int_distribution<std::ranlux24_base, (1ull << 39) + 1ull>                        -0.2389         -0.2389            51            39            51            39
bm_uniform_int_distribution<std::minstd_rand0, (1ull << 39) + (1ull << 38)>                 -0.2123         -0.2123            25            19            25            19
bm_uniform_int_distribution<std::ranlux24_base, (1ull << 39) + (1ull << 38)>                -0.2972         -0.2972            37            26            37            26
bm_uniform_int_distribution<std::minstd_rand0, 1ull << 41>                                  -0.2376         -0.2376            19            15            19            15
bm_uniform_int_distribution<std::ranlux24_base, 1ull << 41>                                 -0.3027         -0.3027            29            20            29            20
bm_uniform_int_distribution<std::minstd_rand0, (1ull << 40) + 1ull>                         -0.1339         -0.1339            35            30            35            30
bm_uniform_int_distribution<std::ranlux24_base, (1ull << 40) + 1ull>                        -0.2215         -0.2215            53            41            53            41
bm_uniform_int_distribution<std::minstd_rand0, (1ull << 40) + (1ull << 39)>                 -0.1610         -0.1610            25            21            25            21
bm_uniform_int_distribution<std::ranlux24_base, (1ull << 40) + (1ull << 39)>                -0.2730         -0.2730            37            27            37            27
OVERALL_GEOMEAN                                                                             -0.3410         -0.3410             0             0             0             0
```

https://github.com/llvm/llvm-project/pull/140161


More information about the libcxx-commits mailing list