public static IntegerNumber operator *(IntegerNumber number1, IntegerNumber number2) { IntegerNumber source1 = number1.ExtendTo(number2.Digits); IntegerNumber source2 = number2.ExtendTo(number1.Digits); ulong[] result = new ulong[source1.Digits * 2]; AsmX64Operations.FastestMultiplication(source1.bits, source2.bits, result, source1.Digits, true); return(new IntegerNumber(result, false)); }
public static bool UnitTestBigMul(int seed) { Random random = new Random(seed); byte[] data = new byte[16]; int length = 6 * 1024; //1024; ulong[] xx = new ulong[length]; ulong[] yy = new ulong[length]; ulong[] zz = new ulong[length * 2]; ulong[] tt = new ulong[length * 2]; ulong[] uu = new ulong[length * 2]; int tries = 1; ulong[] temporaryBuffer = new ulong[AsmX64Operations.GetKaratsubaMultiplicationBufferSize(xx.Length)]; TimeSpan directTime = TimeSpan.Zero; TimeSpan karatsubaTime = TimeSpan.Zero; TimeSpan fourierTime = TimeSpan.Zero; for (int step = tries; --step >= 0;) { for (int i = xx.Length; --i >= 0;) { random.NextBytes(data); xx[i] = BitConverter.ToUInt64(data, 0); yy[i] = BitConverter.ToUInt64(data, 8); } directTime += AsmX64Operations.MeasureTime(() => { AsmX64Operations.Multiply(xx, yy, zz, length); }); karatsubaTime += AsmX64Operations.MeasureTime(() => { AsmX64Operations.Karatsuba(xx, yy, tt, length); }); fourierTime += AsmX64Operations.MeasureTime(() => { AsmX64Operations.FastestMultiplication(xx, yy, uu, length); }); for (int i = length * 2; --i >= 0;) { if (zz[i] != tt[i] || tt[i] != uu[i]) { return(false); } } } int fftBitsPerDigit, fftLog2Size; GetFFTParameters(length, out fftBitsPerDigit, out fftLog2Size); double directOpsSecond = (1.0 * tries * length * length / directTime.TotalSeconds); double karaOpsSecond = tries * Math.Pow(length, LOG2_3) / karatsubaTime.TotalSeconds; double fftOpsSecond = tries * Math.Pow(2.0, fftLog2Size) * (3.0 * fftLog2Size + 4.0) / fourierTime.TotalSeconds; //MessageBox.Show( // "Direct: " + directTime.ToString() + " " + directOpsSecond.ToString("N3") + " ops/sec\r\n" + // "Karatsuba: " + karatsubaTime.ToString() + " " + (directOpsSecond / karaOpsSecond).ToString("N3") + " x constant\r\n" + // "Fourier: " + fourierTime.ToString() + " " + (directOpsSecond / fftOpsSecond).ToString("N3") + " x constant\r\n", "Timings"); return(true); }