From 99084bdc59ec48733856bb5f79648f9e5b114312 Mon Sep 17 00:00:00 2001 From: Roman Snytsar Date: Thu, 17 Apr 2025 06:40:38 -0700 Subject: [PATCH 1/5] Fast discard() for minstd_ramd amd minstd_ramd0 via fast exponentiation --- stl/inc/random | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/stl/inc/random b/stl/inc/random index fa401b630cd..b7598b38b0b 100644 --- a/stl/inc/random +++ b/stl/inc/random @@ -617,12 +617,37 @@ public: void discard(unsigned long long _Nskip) noexcept /* strengthened */ { // discard _Nskip elements - auto _Temp = _Prev; - for (; 0 < _Nskip; --_Nskip) { - _Temp = _Next_linear_congruential_value<_Uint, _Ax, _Cx, _Mx>(_Temp); - } + if constexpr (_Cx == 0 && _Mx == 2147483647) { + // for minstd_rand and minstd_rand0 we can improve performance by + // performing fast exponentiation and avoiding constant divisions + auto _Temp = static_cast(_Prev); + auto _Mul = static_cast(_Ax); + + for (;;) { + if (_Nskip & 1) { + _Temp = _Temp * _Mul; + _Temp = (_Temp >> 31) + (_Temp & _Mx); + _Temp = _Temp < _Mx ? _Temp : _Temp - _Mx; + } + if (_Nskip >>= 1) { + _Mul = _Mul * _Mul; + _Mul = (_Mul >> 31) + (_Mul & _Mx); + _Mul = _Mul < _Mx ? _Mul : _Mul - _Mx; + } else { + break; + } + } - _Prev = _Temp; + _Prev = static_cast<_Uint>(_Temp); + } else { + auto _Temp = _Prev; + + for (; 0 < _Nskip; --_Nskip) { + _Temp = _Next_linear_congruential_value<_Uint, _Ax, _Cx, _Mx>(_Temp); + } + + _Prev = _Temp; + } } _NODISCARD friend bool operator==( From f1f1a07793c5fc53c1247199b16ffee010d6fd21 Mon Sep 17 00:00:00 2001 From: Roman Snytsar Date: Thu, 17 Apr 2025 07:05:00 -0700 Subject: [PATCH 2/5] clang formatting --- ...hmark-random_integer_generation-results.csv | 18 ++++++++++++++++++ stl/inc/random | 14 +++++++------- 2 files changed, 25 insertions(+), 7 deletions(-) create mode 100644 benchmark-random_integer_generation-results.csv diff --git a/benchmark-random_integer_generation-results.csv b/benchmark-random_integer_generation-results.csv new file mode 100644 index 00000000000..ec1d7b66ff1 --- /dev/null +++ b/benchmark-random_integer_generation-results.csv @@ -0,0 +1,18 @@ +2025-04-16T09:51:31-07:00 +Running out\bench\benchmark-random_integer_generation +Run on (24 X 2000 MHz CPU s) +CPU Caches: + L1 Data 48 KiB (x12) + L1 Instruction 32 KiB (x12) + L2 Unified 2048 KiB (x12) + L3 Unified 30720 KiB (x1) +name,iterations,real_time,cpu_time,time_unit,bytes_per_second,items_per_second,label,error_occurred,error_message +"BM_mt19937",100000000,6.05397,6.09375,ns,,,,, +"BM_mt19937_64",112000000,6.10599,5.99888,ns,,,,, +"BM_lcg",194782609,3.53956,3.52958,ns,,,,, +"BM_raw_mt19937_old",56000000,11.3503,11.1607,ns,,,,, +"BM_raw_mt19937_new",112000000,7.07062,7.11496,ns,,,,, +"BM_raw_mt19937_64_old",56000000,12.7296,12.5558,ns,,,,, +"BM_raw_mt19937_64_new",89600000,8.04124,8.02176,ns,,,,, +"BM_raw_lcg_old",32000000,23.7477,23.9258,ns,,,,, +"BM_raw_lcg_new",26352941,28.0717,28.4598,ns,,,,, diff --git a/stl/inc/random b/stl/inc/random index b7598b38b0b..38d02ba6ee0 100644 --- a/stl/inc/random +++ b/stl/inc/random @@ -621,7 +621,7 @@ public: // for minstd_rand and minstd_rand0 we can improve performance by // performing fast exponentiation and avoiding constant divisions auto _Temp = static_cast(_Prev); - auto _Mul = static_cast(_Ax); + auto _Mul = static_cast(_Ax); for (;;) { if (_Nskip & 1) { @@ -638,15 +638,15 @@ public: } } - _Prev = static_cast<_Uint>(_Temp); + _Prev = static_cast<_Uint>(_Temp); } else { - auto _Temp = _Prev; + auto _Temp = _Prev; - for (; 0 < _Nskip; --_Nskip) { - _Temp = _Next_linear_congruential_value<_Uint, _Ax, _Cx, _Mx>(_Temp); - } + for (; 0 < _Nskip; --_Nskip) { + _Temp = _Next_linear_congruential_value<_Uint, _Ax, _Cx, _Mx>(_Temp); + } - _Prev = _Temp; + _Prev = _Temp; } } From 1ce1a09d57bb715d7ac14a002705a6649c2b2b64 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 17 Apr 2025 15:52:03 -0700 Subject: [PATCH 3/5] Delete mistakenly added CSV file. --- ...hmark-random_integer_generation-results.csv | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 benchmark-random_integer_generation-results.csv diff --git a/benchmark-random_integer_generation-results.csv b/benchmark-random_integer_generation-results.csv deleted file mode 100644 index ec1d7b66ff1..00000000000 --- a/benchmark-random_integer_generation-results.csv +++ /dev/null @@ -1,18 +0,0 @@ -2025-04-16T09:51:31-07:00 -Running out\bench\benchmark-random_integer_generation -Run on (24 X 2000 MHz CPU s) -CPU Caches: - L1 Data 48 KiB (x12) - L1 Instruction 32 KiB (x12) - L2 Unified 2048 KiB (x12) - L3 Unified 30720 KiB (x1) -name,iterations,real_time,cpu_time,time_unit,bytes_per_second,items_per_second,label,error_occurred,error_message -"BM_mt19937",100000000,6.05397,6.09375,ns,,,,, -"BM_mt19937_64",112000000,6.10599,5.99888,ns,,,,, -"BM_lcg",194782609,3.53956,3.52958,ns,,,,, -"BM_raw_mt19937_old",56000000,11.3503,11.1607,ns,,,,, -"BM_raw_mt19937_new",112000000,7.07062,7.11496,ns,,,,, -"BM_raw_mt19937_64_old",56000000,12.7296,12.5558,ns,,,,, -"BM_raw_mt19937_64_new",89600000,8.04124,8.02176,ns,,,,, -"BM_raw_lcg_old",32000000,23.7477,23.9258,ns,,,,, -"BM_raw_lcg_new",26352941,28.0717,28.4598,ns,,,,, From 843520a725dd95016ff4f580c20aaf3abcea95a7 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 17 Apr 2025 15:53:57 -0700 Subject: [PATCH 4/5] Add newline. --- stl/inc/random | 1 + 1 file changed, 1 insertion(+) diff --git a/stl/inc/random b/stl/inc/random index 38d02ba6ee0..bc50e0c9f0e 100644 --- a/stl/inc/random +++ b/stl/inc/random @@ -629,6 +629,7 @@ public: _Temp = (_Temp >> 31) + (_Temp & _Mx); _Temp = _Temp < _Mx ? _Temp : _Temp - _Mx; } + if (_Nskip >>= 1) { _Mul = _Mul * _Mul; _Mul = (_Mul >> 31) + (_Mul & _Mx); From 3ee32da6f107358ae95361909ab6b6fc869ff213 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 17 Apr 2025 16:37:31 -0700 Subject: [PATCH 5/5] Add discard() benchmarks. --- benchmarks/src/random_integer_generation.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/benchmarks/src/random_integer_generation.cpp b/benchmarks/src/random_integer_generation.cpp index 9c1615a5bc1..7a65f2b1f2e 100644 --- a/benchmarks/src/random_integer_generation.cpp +++ b/benchmarks/src/random_integer_generation.cpp @@ -31,6 +31,23 @@ void BM_lcg(benchmark::State& state) { } BENCHMARK(BM_lcg); +/// Test discard() + +template +void BM_discard(benchmark::State& state) { + Engine gen; + const auto n = static_cast(state.range(0)); + for (auto _ : state) { + gen.discard(n); + benchmark::DoNotOptimize(gen()); + } +} +BENCHMARK(BM_discard)->Range(0, 1 << 18); +BENCHMARK(BM_discard)->Range(0, 1 << 18); +BENCHMARK(BM_discard)->Range(0, 1 << 18); + +/// Support machinery for testing _Rng_from_urng and _Rng_from_urng_v2 + std::uint32_t GetMax() { std::mt19937 gen; std::uniform_int_distribution dist(10'000'000, 20'000'000);