This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
|
||||
namespace Just.PreciseMath.Benchmarks;
|
||||
|
||||
/// <summary>Isolates ordinary/fallback exponent transitions, not special-value handling.</summary>
|
||||
[MemoryDiagnoser]
|
||||
[CategoriesColumn]
|
||||
public class ArithmeticBoundaryBenchmarks
|
||||
{
|
||||
private DoubleDouble _addLeft;
|
||||
private DoubleDouble _addRight;
|
||||
private DoubleDouble _multiplyLeft;
|
||||
private DoubleDouble _divideLeft;
|
||||
private DoubleDouble _factor;
|
||||
|
||||
[Params(false, true)]
|
||||
public bool Fallback { get; set; }
|
||||
|
||||
[GlobalSetup]
|
||||
public void Setup()
|
||||
{
|
||||
int offset = Fallback ? 1 : 0;
|
||||
_addLeft = Pair(1020 + offset);
|
||||
_addRight = Pair(1019);
|
||||
_multiplyLeft = Pair(900 + offset);
|
||||
_divideLeft = Pair(450 + offset);
|
||||
_factor = DoubleDouble.FromComponents(1.125, Math.ScaleB(1.0, -56));
|
||||
// Pin dispatch assumptions to the current source guards. Both signs/orders
|
||||
// remain finite; boundary timing is intentionally separate from ordinary data.
|
||||
if ((Math.ILogB(_addLeft.High) > 1020) != Fallback
|
||||
|| (Math.ILogB(_multiplyLeft.High) + Math.ILogB(_factor.High) > 900) != Fallback
|
||||
|| (Math.Abs(Math.ILogB(_divideLeft.High)) > 450) != Fallback)
|
||||
{
|
||||
throw new InvalidOperationException("Boundary fixture does not select the requested guard branch.");
|
||||
}
|
||||
}
|
||||
|
||||
private static DoubleDouble Pair(int exponent)
|
||||
{
|
||||
return DoubleDouble.FromComponents(Math.ScaleB(1.0, exponent), Math.ScaleB(1.0, exponent - 56));
|
||||
}
|
||||
|
||||
[Benchmark, BenchmarkCategory("Addition")]
|
||||
public DoubleDouble DDAdd()
|
||||
{
|
||||
return _addLeft + _addRight;
|
||||
}
|
||||
|
||||
[Benchmark, BenchmarkCategory("Addition")]
|
||||
public DoubleDouble DDScalarAdd()
|
||||
{
|
||||
return _addLeft + _addRight.High;
|
||||
}
|
||||
|
||||
[Benchmark, BenchmarkCategory("Addition")]
|
||||
public DoubleDouble ScalarDDAdd()
|
||||
{
|
||||
return _addLeft.High + _addRight;
|
||||
}
|
||||
|
||||
[Benchmark, BenchmarkCategory("Subtraction")]
|
||||
public DoubleDouble DDSubtract()
|
||||
{
|
||||
return _addLeft - _addRight;
|
||||
}
|
||||
|
||||
[Benchmark, BenchmarkCategory("Subtraction")]
|
||||
public DoubleDouble DDScalarSubtract()
|
||||
{
|
||||
return _addLeft - _addRight.High;
|
||||
}
|
||||
|
||||
[Benchmark, BenchmarkCategory("Subtraction")]
|
||||
public DoubleDouble ScalarDDSubtract()
|
||||
{
|
||||
return _addLeft.High - _addRight;
|
||||
}
|
||||
|
||||
[Benchmark, BenchmarkCategory("Multiplication")]
|
||||
public DoubleDouble DDMultiply()
|
||||
{
|
||||
return _multiplyLeft * _factor;
|
||||
}
|
||||
|
||||
[Benchmark, BenchmarkCategory("Multiplication")]
|
||||
public DoubleDouble DDScalarMultiply()
|
||||
{
|
||||
return _multiplyLeft * _factor.High;
|
||||
}
|
||||
|
||||
[Benchmark, BenchmarkCategory("Multiplication")]
|
||||
public DoubleDouble ScalarDDMultiply()
|
||||
{
|
||||
return _multiplyLeft.High * _factor;
|
||||
}
|
||||
|
||||
[Benchmark, BenchmarkCategory("Division")]
|
||||
public DoubleDouble DDDivide()
|
||||
{
|
||||
return _divideLeft / _factor;
|
||||
}
|
||||
|
||||
[Benchmark, BenchmarkCategory("Division")]
|
||||
public DoubleDouble DDScalarDivide()
|
||||
{
|
||||
return _divideLeft / _factor.High;
|
||||
}
|
||||
|
||||
[Benchmark, BenchmarkCategory("Division")]
|
||||
public DoubleDouble ScalarDDDivide()
|
||||
{
|
||||
return _factor.High / _divideLeft;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user