Files
even-perfect-numbers-scanner/EvenPerfectBitScanner.Benchmarks/GpuUInt128ScalarMulModBenchmarks.cs
2025-10-17 02:40:51 +02:00

70 lines
2.4 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using PerfectNumbers.Core.Gpu;
namespace EvenPerfectBitScanner.Benchmarks;
[SimpleJob(RuntimeMoniker.Net80)]
[MemoryDiagnoser]
public class GpuUInt128ScalarMulModBenchmarks
{
private static readonly ScalarMulModInput[] Inputs = new ScalarMulModInput[]
{
new(
new GpuUInt128(0x0000_0000_0000_0000UL, 0x0000_0000_0000_0011UL),
0x0000_0000_0000_0013UL,
new GpuUInt128(0x0000_0000_0000_0001UL, 0x0000_0000_0000_00FFUL),
"TinyOperands"),
new(
new GpuUInt128(0x0123_4567_89AB_CDEFUL, 0xFEDC_BA98_7654_3210UL),
0x0F1E_2D3C_4B5A_6978UL,
new GpuUInt128(0x0FFF_FFFF_FFFF_FFFFUL, 0xFFFF_FFFF_FFFF_FFC3UL),
"MixedMagnitude"),
new(
new GpuUInt128(0x8000_0000_0000_0000UL, 0x0000_0000_0000_0001UL),
0x7FFF_FFFF_FFFF_FFFBUL,
new GpuUInt128(0x7FFF_FFFF_FFFF_FFFFUL, 0xFFFF_FFFF_FFFF_FFF1UL),
"HighWordDominant"),
};
[ParamsSource(nameof(GetInputs))]
public ScalarMulModInput Input { get; set; }
public static IEnumerable<ScalarMulModInput> GetInputs() => Inputs;
/// <summary>
/// Allocates a temporary <see cref="GpuUInt128"/> for the scalar operand; landed at 164–194 ns across the three workloads,
/// making it the slower option.
/// </summary>
/// <remarks>
/// Observed means: HighWordDominant 193.7 ns (1.00×), MixedMagnitude 180.7 ns, TinyOperands 164.0 ns.
/// </remarks>
[Benchmark(Baseline = true)]
public GpuUInt128 StructAllocating()
{
GpuUInt128 value = Input.Left;
value.MulMod(new GpuUInt128(Input.Right), Input.Modulus);
return value;
}
/// <summary>
/// Specialized scalar path that multiplies directly by the 64-bit factor; saves 6–13% by avoiding the temporary (154–192 ns).
/// </summary>
/// <remarks>
/// Observed means: HighWordDominant 192.1 ns (0.99×), MixedMagnitude 168.5 ns, TinyOperands 154.2 ns.
/// </remarks>
[Benchmark]
public GpuUInt128 SpecializedScalar()
{
GpuUInt128 value = Input.Left;
value.MulMod(Input.Right, Input.Modulus);
return value;
}
public readonly record struct ScalarMulModInput(GpuUInt128 Left, ulong Right, GpuUInt128 Modulus, string Name)
{
public override string ToString() => Name;
}
}