Optimizations and tiny cleanup

This commit is contained in:
Marek Lemańczyk committed 2025-10-01 13:02:07 +02:00
1 parent e14cb5df52
commit 513fc7acb0
6 files changed
+44 -41

No files matched your search

@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
@@ -29,17 +29,17 @@ public class GpuUInt128BinaryGcdBenchmarks
[Benchmark(Baseline = true)]
public GpuUInt128 ReusedVariables()
{
return GpuUInt128.BinaryGcd(Input.Left, Input.Right);
return BinaryGcdWithReusedVariables(Input.Left, Input.Right);
}
[Benchmark]
public GpuUInt128 TemporaryStructPerIteration()
{
return BinaryGcdWithTemporary(Input.Left, Input.Right);
return GpuUInt128.BinaryGcd(Input.Left, Input.Right);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static GpuUInt128 BinaryGcdWithTemporary(GpuUInt128 u, GpuUInt128 v)
private static GpuUInt128 BinaryGcdWithReusedVariables(GpuUInt128 u, GpuUInt128 v)
{
if (u.IsZero)
{
@@ -51,7 +51,12 @@ public class GpuUInt128BinaryGcdBenchmarks
return u;
}
int shift = GpuUInt128.TrailingZeroCount(new GpuUInt128(u.High | v.High, u.Low | v.Low));
ulong combinedLow = u.Low | v.Low;
ulong combinedHigh = u.High | v.High;
int shift = combinedLow != 0UL
? BitOperations.TrailingZeroCount(combinedLow)
: 64 + BitOperations.TrailingZeroCount(combinedHigh);
int zu = GpuUInt128.TrailingZeroCount(u);
u >>= zu;
@@ -24,7 +24,7 @@ public class GpuUInt128Mul64Benchmarks
public static IEnumerable<Mul64Input> GetInputs() => Inputs;
[Benchmark(Baseline = true)]
public GpuUInt128 HighProductMaterialisedInLocal()
public GpuUInt128 HighProductMaterializedInLocal()
{
GpuUInt128 value = Input.Multiplicand;
value.Mul64(Input.Multiplier);
@@ -10,8 +10,8 @@ namespace EvenPerfectBitScanner.Benchmarks;
[MemoryDiagnoser]
public class GpuUInt128MulModBenchmarks
{
private static readonly MulModInput[] Inputs = new MulModInput[]
{
private static readonly MulModInput[] Inputs =
[
new(
new GpuUInt128(0UL, 5UL),
new GpuUInt128(0UL, 7UL),
@@ -32,7 +32,7 @@ public class GpuUInt128MulModBenchmarks
new GpuUInt128(0x7FFF_FFFF_FFFF_FFFFUL, 0x8000_0000_0000_0000UL),
new GpuUInt128(0x7FFF_FFFF_FFFF_FFFFUL, 0xFFFF_FFFF_FFFF_FFF1UL),
"MixedMagnitude"),
};
];
[ParamsSource(nameof(GetInputs))]
public MulModInput Input { get; set; }
@@ -42,6 +42,7 @@ public class GpuUInt128MulModBenchmarks
[Benchmark(Baseline = true)]
public GpuUInt128 InPlaceMulMod()
{
// TODO: Switch the extension method to allocate per iteration, as it's faster. Keep the benchmarks.
GpuUInt128 value = Input.Left;
value.MulMod(Input.Right, Input.Modulus);
return value;
@@ -56,6 +57,7 @@ public class GpuUInt128MulModBenchmarks
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static GpuUInt128 MulModInline(GpuUInt128 left, GpuUInt128 right, GpuUInt128 modulus)
{
// Reuse the variables to new instances and lower registry pressure, if possible.
GpuUInt128 a = left;
GpuUInt128 b = right;
GpuUInt128 result = new();
@@ -42,6 +42,7 @@ public class GpuUInt128MulModByLimbBenchmarks
[Benchmark]
public GpuUInt128 InPlaceReduction()
{
// TODO: Switch the extension method back to legacy method, as it's faster. Keep the benchmarks.
GpuUInt128 value = Input.Left;
value.MulModByLimb(Input.Right, Input.Modulus);
return value;