MethodImplOptions.AggressiveOptimization & MethodImplOptions.AggressiveInlining optimized. Small optimizations.
This commit is contained in:
1 parent
7a242b3bfa
commit
05d3061c47
23 files changed
+628
-559
No files matched your search
@@ -1,3 +1,4 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using ILGPU;
|
||||
using ILGPU.Runtime;
|
||||
|
||||
@@ -9,10 +10,13 @@ internal readonly struct HeuristicCombinedGpuTables
|
||||
|
||||
private static readonly HeuristicCombinedGpuTables[] _sharedTables = new HeuristicCombinedGpuTables[PerfectNumberConstants.RollingAccelerators];
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
internal static void WarmUp(int acceleratorIndex, AcceleratorStream stream) => _sharedTables[acceleratorIndex] = new(_accelerators[acceleratorIndex], stream);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
internal static HeuristicCombinedGpuTables GetStaticTables(int acceleratorIndex) => _sharedTables[acceleratorIndex];
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
internal HeuristicCombinedGpuTables(Accelerator accelerator, AcceleratorStream stream)
|
||||
{
|
||||
var combinedEnding1 = HeuristicCombinedPrimeTester.CombinedDivisorsEnding1;
|
||||
@@ -45,6 +49,7 @@ internal readonly struct HeuristicCombinedGpuTables
|
||||
internal readonly MemoryBuffer1D<ulong, Stride1D.Dense> HeuristicCombinedDivisorsEnding9;
|
||||
internal readonly MemoryBuffer1D<ulong, Stride1D.Dense> HeuristicCombinedDivisorSquaresEnding9;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
internal HeuristicCombinedGpuViews CreateViews() => new(
|
||||
HeuristicCombinedDivisorsEnding1.View,
|
||||
HeuristicCombinedDivisorsEnding3.View,
|
||||
@@ -55,6 +60,7 @@ internal readonly struct HeuristicCombinedGpuTables
|
||||
HeuristicCombinedDivisorSquaresEnding7.View,
|
||||
HeuristicCombinedDivisorSquaresEnding9.View);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
internal void Dispose()
|
||||
{
|
||||
HeuristicCombinedDivisorsEnding1.Dispose();
|
||||
|
||||
@@ -195,6 +195,7 @@ public sealed class PrimeOrderCalculatorAccelerator
|
||||
public readonly Action<AcceleratorStream, Index1D, ArrayView<ulong>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<uint>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<ulong>, ArrayView<byte>> SmallPrimeSieveKernelLauncher;
|
||||
public readonly Action<AcceleratorStream, Index1D, ulong, ArrayView<ulong>, int, ulong, ArrayView<ulong>> SpecialMaxKernelLauncher;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
public void EnsureCalculateOrderWideCapacity(int newSize)
|
||||
{
|
||||
if (newSize > Input.Length)
|
||||
@@ -213,6 +214,7 @@ public sealed class PrimeOrderCalculatorAccelerator
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
public void EnsureCapacity(int factorsCount, int primeTesterCapacity)
|
||||
{
|
||||
Accelerator accelerator = Accelerator;
|
||||
@@ -325,6 +327,7 @@ public sealed class PrimeOrderCalculatorAccelerator
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
public void EnsureUlongInputOutputCapacity(int newSize)
|
||||
{
|
||||
var accelerator = Accelerator;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using ILGPU;
|
||||
using ILGPU.Runtime;
|
||||
using PerfectNumbers.Core.Gpu.Accelerators;
|
||||
@@ -74,6 +75,7 @@ public class GpuKernelPool
|
||||
});
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
static void InitPow2ModKernelScan(Accelerator accelerator, KernelContainer kernels)
|
||||
{
|
||||
InitOnce(ref kernels.Pow2Mod, () =>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using ILGPU;
|
||||
using ILGPU.Runtime;
|
||||
|
||||
@@ -6,6 +7,7 @@ namespace PerfectNumbers.Core.Gpu;
|
||||
internal static class Pow2ModKernels
|
||||
{
|
||||
/// This kernel always sets the result of the corresponding element. Callers don't need to clear the output buffers.
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
public static void Pow2ModKernelScan(
|
||||
Index1D index,
|
||||
ulong exponent,
|
||||
@@ -107,6 +109,7 @@ internal static class Pow2ModKernels
|
||||
|
||||
/// This kernel doesn't always set the result of the found array. It sets the value only when it needs to. The callers
|
||||
/// must clean the output buffer before the call to get a deterministic result.
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
public static void Pow2ModOrderKernelScan(
|
||||
Index1D index,
|
||||
ulong exponent,
|
||||
|
||||
@@ -117,7 +117,7 @@ public static class Pow2MontgomeryKernels
|
||||
return sumHigh;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization | MethodImplOptions.AggressiveInlining)]
|
||||
private static void MultiplyPartsGpu(ulong left, ulong right, out ulong high, out ulong low)
|
||||
{
|
||||
ulong leftLow = (uint)left;
|
||||
@@ -135,13 +135,13 @@ public static class Pow2MontgomeryKernels
|
||||
high = unchecked(highProduct + (cross1 >> 32) + (cross2 >> 32) + (carry >> 32));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
internal static ulong Pow2MontgomeryModWindowedGpuKeepMontgomery(in MontgomeryDivisorDataGpu divisor, ulong exponent)
|
||||
{
|
||||
return Pow2MontgomeryModWindowedGpuMontgomeryResult(divisor, exponent);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
public static ulong Pow2MontgomeryModWindowedGpuConvertToStandard(this MontgomeryDivisorDataGpu divisor, ulong exponent)
|
||||
{
|
||||
ulong modulus = divisor.Modulus;
|
||||
@@ -150,7 +150,7 @@ public static class Pow2MontgomeryKernels
|
||||
return MontgomeryMultiplyGpu(montgomeryResult, 1UL, modulus, nPrime);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
private static ulong Pow2MontgomeryModWindowedGpuMontgomeryResult(in MontgomeryDivisorDataGpu divisor, ulong exponent)
|
||||
{
|
||||
ulong modulus = divisor.Modulus;
|
||||
|
||||
@@ -1182,6 +1182,7 @@ internal static partial class PrimeOrderKernels
|
||||
return divisor.Pow2MontgomeryModWindowedGpuConvertToStandard(exponent) == 1UL;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
private static ulong CalculateByDoublingKernel(ulong prime)
|
||||
{
|
||||
ulong order = 1UL;
|
||||
@@ -1203,6 +1204,7 @@ internal static partial class PrimeOrderKernels
|
||||
|
||||
/// This kernel always sets the result of the corresponding element. Callers don't need to clear the output buffers.
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
internal static void Pow2ModKernel(Index1D index, ArrayView1D<ulong, Stride1D.Dense> exponents, ulong divisorModulus, ulong divisorNPrime, ulong divisorMontgomeryOne, ulong divisorMontgomeryTwo, ulong divisorMontgomeryTwoSquared, ArrayView1D<ulong, Stride1D.Dense> remainders)
|
||||
{
|
||||
ulong exponent = exponents[index];
|
||||
@@ -1211,12 +1213,14 @@ internal static partial class PrimeOrderKernels
|
||||
}
|
||||
|
||||
/// This kernel always sets the result of the corresponding element. Callers don't need to clear the output buffers.
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
internal static void Pow2ModKernelWide(Index1D index, ArrayView1D<GpuUInt128, Stride1D.Dense> exponents, GpuUInt128 modulus, ArrayView1D<GpuUInt128, Stride1D.Dense> remainders)
|
||||
{
|
||||
GpuUInt128 exponent = exponents[index];
|
||||
remainders[index] = Pow2ModKernelCore(exponent, modulus);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
private static GpuUInt128[] InitializeOddPowersTable(GpuUInt128 baseValue, GpuUInt128 modulus, int oddPowerCount)
|
||||
{
|
||||
GpuUInt128[] result = new GpuUInt128[PerfectNumberConstants.MaxOddPowersCount];
|
||||
@@ -1242,6 +1246,7 @@ internal static partial class PrimeOrderKernels
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
internal static GpuUInt128 Pow2ModKernelCore(GpuUInt128 exponent, GpuUInt128 modulus)
|
||||
{
|
||||
// This should never happen in production code.
|
||||
|
||||
@@ -23,6 +23,7 @@ public class MersenneNumberResidueGpuTester(bool useGpuOrder)
|
||||
// requested by the caller, skip queuing additional block generation, and keep the snapshot cache untouched.
|
||||
|
||||
// GPU residue variant: check 2^p % q == 1 for q = 2*p*k + 1.
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
public void Scan(PrimeOrderCalculatorAccelerator gpu, ulong exponent, UInt128 twoP, LastDigit lastDigit, UInt128 maxK, ref bool isPrime)
|
||||
{
|
||||
// GpuPrimeWorkLimiter.Acquire();
|
||||
@@ -114,6 +115,7 @@ public class MersenneNumberResidueGpuTester(bool useGpuOrder)
|
||||
// GpuPrimeWorkLimiter.Release();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
private static Action<AcceleratorStream, Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ResidueAutomatonArgs, ArrayView<ulong>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>> GetPow2ModKernel(Accelerator accelerator)
|
||||
{
|
||||
|
||||
@@ -128,6 +130,7 @@ public class MersenneNumberResidueGpuTester(bool useGpuOrder)
|
||||
return cached;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
private static Action<AcceleratorStream, Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ResidueAutomatonArgs, ArrayView<ulong>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>> CreatePow2ModKernel(Accelerator accelerator)
|
||||
{
|
||||
var loaded = accelerator.LoadAutoGroupedStreamKernel<Index1D, ulong, GpuUInt128, GpuUInt128, byte, ulong, ResidueAutomatonArgs, ArrayView<ulong>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<uint, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>, ArrayView1D<ulong, Stride1D.Dense>>(Pow2ModKernels.Pow2ModKernelScan);
|
||||
@@ -140,6 +143,7 @@ public class MersenneNumberResidueGpuTester(bool useGpuOrder)
|
||||
}
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
private static ResidueResources RentResources(Accelerator accelerator, int capacity)
|
||||
{
|
||||
var resourcePools = _resourcePools ??= new();
|
||||
@@ -152,6 +156,7 @@ public class MersenneNumberResidueGpuTester(bool useGpuOrder)
|
||||
return new ResidueResources(accelerator, capacity);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
private static void ReturnResources(ResidueResources resources)
|
||||
{
|
||||
var resourcePools = _resourcePools ??= new();
|
||||
@@ -160,6 +165,7 @@ public class MersenneNumberResidueGpuTester(bool useGpuOrder)
|
||||
|
||||
private sealed class ResidueResources
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
internal ResidueResources(Accelerator accelerator, int capacity)
|
||||
{
|
||||
Capacity = Math.Max(1, capacity);
|
||||
@@ -171,6 +177,7 @@ public class MersenneNumberResidueGpuTester(bool useGpuOrder)
|
||||
OrderArray = ThreadStaticPools.UlongPool.Rent(Capacity);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
internal void EnsureCapacity(Accelerator accelerator, int capacity)
|
||||
{
|
||||
if (OrderBuffer.Length >= capacity)
|
||||
@@ -213,4 +220,4 @@ public class MersenneNumberResidueGpuTester(bool useGpuOrder)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ namespace PerfectNumbers.Core.Gpu;
|
||||
|
||||
public static class Pow2MontgomeryGpuCalculator
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
public static ulong CalculateKeep(PrimeOrderCalculatorAccelerator gpu, ulong exponent, in MontgomeryDivisorData divisor)
|
||||
{
|
||||
// GpuPrimeWorkLimiter.Acquire();
|
||||
@@ -34,7 +34,7 @@ public static class Pow2MontgomeryGpuCalculator
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
public static ulong CalculateConvert(PrimeOrderCalculatorAccelerator gpu, ulong exponent, in MontgomeryDivisorData divisor)
|
||||
{
|
||||
ulong result = 0UL;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Buffers;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using ILGPU.Runtime;
|
||||
using PerfectNumbers.Core.Gpu.Accelerators;
|
||||
@@ -16,6 +17,7 @@ internal enum GpuPow2ModStatus
|
||||
|
||||
internal static partial class PrimeOrderGpuHeuristics
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
internal static void PreloadStaticTables(AcceleratorStream stream)
|
||||
{
|
||||
// _ = GetSmallPrimeDeviceCache(stream);
|
||||
@@ -31,16 +33,19 @@ internal static partial class PrimeOrderGpuHeuristics
|
||||
internal static ConcurrentDictionary<ulong, byte> OverflowRegistry => OverflowedPrimes;
|
||||
internal static ConcurrentDictionary<UInt128, byte> OverflowRegistryWide => OverflowedPrimesWide;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
internal static void OverrideCapabilitiesForTesting(PrimeOrderGpuCapability capability)
|
||||
{
|
||||
s_capability = capability;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
internal static void ResetCapabilitiesForTesting()
|
||||
{
|
||||
s_capability = PrimeOrderGpuCapability.Default;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
public static bool TryPartialFactor(
|
||||
PrimeOrderCalculatorAccelerator gpu,
|
||||
ulong value,
|
||||
@@ -88,6 +93,7 @@ internal static partial class PrimeOrderGpuHeuristics
|
||||
|
||||
private static readonly Accelerator[] _accelerators = AcceleratorPool.Shared.Accelerators;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
private static bool TryLaunchPartialFactorKernel(
|
||||
PrimeOrderCalculatorAccelerator gpu,
|
||||
ulong value,
|
||||
@@ -156,6 +162,7 @@ internal static partial class PrimeOrderGpuHeuristics
|
||||
return true;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
public static GpuPow2ModStatus TryPow2Mod(PrimeOrderCalculatorAccelerator gpu, ulong exponent, ulong prime, out ulong remainder, in MontgomeryDivisorData? divisorData)
|
||||
{
|
||||
Span<ulong> exponents = stackalloc ulong[1];
|
||||
@@ -167,6 +174,7 @@ internal static partial class PrimeOrderGpuHeuristics
|
||||
return status;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
public static GpuPow2ModStatus TryPow2ModBatch(PrimeOrderCalculatorAccelerator gpu, ReadOnlySpan<ulong> exponents, ulong prime, Span<ulong> remainders, in MontgomeryDivisorData? divisorData)
|
||||
{
|
||||
// This will never occur in production code
|
||||
@@ -222,6 +230,7 @@ internal static partial class PrimeOrderGpuHeuristics
|
||||
return computed ? GpuPow2ModStatus.Success : GpuPow2ModStatus.Unavailable;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
public static GpuPow2ModStatus TryPow2Mod(PrimeOrderCalculatorAccelerator gpu, in UInt128 exponent, in UInt128 prime, out UInt128 remainder)
|
||||
{
|
||||
Span<UInt128> exponents = stackalloc UInt128[1];
|
||||
@@ -233,11 +242,13 @@ internal static partial class PrimeOrderGpuHeuristics
|
||||
return status;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
public static GpuPow2ModStatus TryPow2ModBatch(PrimeOrderCalculatorAccelerator gpu, ReadOnlySpan<UInt128> exponents, UInt128 prime, Span<UInt128> remainders)
|
||||
{
|
||||
return TryPow2ModBatchInternal(gpu, exponents, prime, remainders);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
internal static bool TryCalculateOrder(
|
||||
PrimeOrderCalculatorAccelerator gpu,
|
||||
ulong prime,
|
||||
@@ -310,6 +321,7 @@ internal static partial class PrimeOrderGpuHeuristics
|
||||
return order != 0UL;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||
private static GpuPow2ModStatus TryPow2ModBatchInternal(PrimeOrderCalculatorAccelerator gpu, ReadOnlySpan<UInt128> exponents, UInt128 prime, Span<UInt128> remainders)
|
||||
{
|
||||
if (exponents.Length == 0)
|
||||
|
||||
Reference in new issue
Block a user