public void ProgressiveMultiplicationNumberTest() { AsmX64Operations.SetKaratsubaBreakPoint(16); AsmX64Operations.SetFourierBreakPoint(512); for (int n = 1; n < 2048; n++) { ulong[] input1 = new ulong[n]; ulong[] input2 = new ulong[n]; ulong[] result1 = new ulong[n * 2]; ulong[] result2 = new ulong[n * 2]; ulong[] result3 = new ulong[n * 2]; Random random = new Random(1001); for (int i = n; --i >= 0;) { input1[i] = getUlong(random); input2[i] = getUlong(random); } AsmX64Operations.FastestMultiplication(input1, input2, result1, n, false); AsmX64Operations.Karatsuba(input1, input2, result2, n); AsmX64Operations.Multiply(input1, input2, result3, n); for (int i = n * 2; --i >= 0;) { if (result1[i] != result2[i] || result2[i] != result3[i]) { Assert.IsTrue(false); return; } } } Assert.IsTrue(true); }
static void testMultiplicationSpeed() { Random random = new Random(1001); byte[] number = new byte[16]; int n = 4; int iterations = 1000000; while (true) { AsmX64Operations.SetKaratsubaBreakPoint(n); ulong[] a = new ulong[n]; ulong[] b = new ulong[n]; ulong[] c = new ulong[n * 2]; ulong[] tk = new ulong[AsmX64Operations.GetKaratsubaMultiplicationBufferSize(n)]; for (int i = n; --i >= 0;) { random.NextBytes(number); a[i] = BitConverter.ToUInt64(number, 0); b[i] = BitConverter.ToUInt64(number, 8); } var directTime = AsmX64Operations.MeasureTime(() => { for (int i = iterations; --i >= 0;) { AsmX64Operations.Multiply(a, b, c, n); } }); var karaTime = AsmX64Operations.MeasureTime(() => { for (int i = iterations; --i >= 0;) { AsmX64Operations.Karatsuba(a, b, c, n, tk); } }); if (karaTime.TotalSeconds < directTime.TotalSeconds) { break; } n++; } MessageBox.Show("Kara break point = " + n.ToString()); iterations = 100; //AsmX64Operations.SetKaratsubaBreakPoint(14); n = 4 * 1024; while (true) { AsmX64Operations.SetFourierBreakPoint(n); ulong[] a = new ulong[n]; ulong[] b = new ulong[n]; ulong[] c = new ulong[n * 2]; ulong[] tk = new ulong[AsmX64Operations.GetKaratsubaMultiplicationBufferSize(n)]; for (int i = n; --i >= 0;) { random.NextBytes(number); a[i] = BitConverter.ToUInt64(number, 0); b[i] = BitConverter.ToUInt64(number, 8); } var karaTime = AsmX64Operations.MeasureTime(() => { for (int i = iterations; --i >= 0;) { AsmX64Operations.Karatsuba(a, b, c, n, tk); } }); var fourierTime = AsmX64Operations.MeasureTime(() => { for (int i = iterations; --i >= 0;) { AsmX64Operations.FourierMultiplication(a, b, c, n); } }); if (fourierTime.TotalSeconds < karaTime.TotalSeconds) { break; } n += 512; } MessageBox.Show("Fourier break point = " + n.ToString()); }