using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Jobs; using PerfectNumbers.Core; using PerfectNumbers.Core.Gpu.Accelerators; using PerfectNumbers.Core.Gpu.Kernels; namespace EvenPerfectBitScanner.Benchmarks; /// /// Benchmarks GPU Montgomery exponentiation helpers for exponents at or above 138 million. /// The sample set is generated once and reused across all benchmark methods so every variant /// processes the same data without incurring repeated initialization costs. /// [MemoryDiagnoser] [SimpleJob(RuntimeMoniker.Net80, launchCount: 1, warmupCount: 1, iterationCount: 5)] public class Pow2MontgomeryModWindowedKeepMontgomeryGpuBenchmarks { private Pow2MontgomeryModWindowedBenchmarkInputs _inputs = null!; [GlobalSetup] public void Setup() { _inputs = Pow2MontgomeryModWindowedBenchmarkInputsProvider.Instance; } /// /// Baseline GPU windowed Montgomery exponentiation that converts back to the standard residue. /// [Benchmark(Baseline = true)] public ulong WindowedMontgomeryConvert() { ulong checksum = 0UL; Pow2MontgomeryModWindowedBenchmarkCase[] cases = _inputs.Cases; var gpu = PrimeOrderCalculatorAccelerator.Rent(1); for (int i = 0; i < cases.Length; i++) { ref readonly Pow2MontgomeryModWindowedBenchmarkCase current = ref cases[i]; checksum ^= current.Exponent.Pow2MontgomeryModWindowedConvertGpu(gpu, current.Divisor); } PrimeOrderCalculatorAccelerator.Return(gpu); return checksum; } /// /// GPU windowed Montgomery exponentiation that keeps the result in the Montgomery domain. /// [Benchmark] public ulong WindowedMontgomeryKeep() { ulong checksum = 0UL; Pow2MontgomeryModWindowedBenchmarkCase[] cases = _inputs.Cases; var gpu = PrimeOrderCalculatorAccelerator.Rent(1); for (int i = 0; i < cases.Length; i++) { ref readonly Pow2MontgomeryModWindowedBenchmarkCase current = ref cases[i]; checksum ^= current.Exponent.Pow2MontgomeryModWindowedKeepGpu(gpu, current.Divisor); } PrimeOrderCalculatorAccelerator.Return(gpu); return checksum; } /// /// GPU windowed modular exponentiation without Montgomery reduction for comparison. /// [Benchmark] public ulong WindowedStandardMod() { ulong checksum = 0UL; Pow2MontgomeryModWindowedBenchmarkCase[] cases = _inputs.Cases; for (int i = 0; i < cases.Length; i++) { ref readonly Pow2MontgomeryModWindowedBenchmarkCase current = ref cases[i]; checksum ^= current.Exponent.Pow2ModWindowedGpu(current.Modulus); } return checksum; } }