> Запускать в Release-режиме без подключенного отладчика! Результаты от C++(нативной реализации) практически не отличаются. Первоначально я вытащил Windows-версию, а потом самостоятельно переписал в кроссплатформенную версию, чтобы код можно было запускать в комплиляторе на mac os. Переписать пришлось потому что в windows-версии есть зависимости, которые несовместимы с другими ОС. И теперь кроссплатформенный код можно запускать на любом ОС, где поддерживается .Net ### Кроссплатформенная версия ```csharp using System.Diagnostics; class Program { static void Main(string[] args) { long start, end; long milliseconds = 6000; // по умолчанию тест запускается на 6 секунд int randomBufferSize = 20000; // наполняем буфер 32-битных чисел для участия в тесте List<int> mem1 = new List<int>(); Random rnd1 = new Random(777); for (int n = 0; n < randomBufferSize; n++) { int a = rnd1.Next(int.MaxValue) << 17; int b = rnd1.Next(int.MaxValue); int r = a + b; mem1.Add(r == 0 ? 1 : r); } // наполняем буфер 64-битных чисел для участия в тесте List<long> mem2 = new List<long>(); Random rnd2 = new Random(777); for (int n = 0; n < randomBufferSize; n++) { long a = ((long)rnd2.Next(int.MaxValue)) << 15; long b = (a + rnd2.Next(int.MaxValue)) << 15; long c = (b + rnd2.Next(int.MaxValue)) << 15; long d = rnd2.Next(int.MaxValue); long r = c + d; mem2.Add(r == 0 ? 1 : r); } int mem_index = 0; long v27 = 0; const int addSubOpsCount = 1000; const int mulDivOpsCount = 500; int v11, v17, v4, v10, v12, v13, v18; long v15, v16, v14, v8, v9, v31, i; // Запускаем таймер для подсчета числа тиков Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); do { // параметры 32-битного эксперимента v4 = mem1[mem_index + 1]; v10 = mem1[mem_index + 0]; v11 = mem1[mem_index + 2]; v12 = mem1[mem_index + 3]; v13 = mem1[mem_index + 4]; v17 = mem1[mem_index + 5]; v18 = v4; // параметры 64-битного эксперимента v14 = mem2[mem_index + 0]; v8 = mem2[mem_index + 1]; v15 = mem2[mem_index + 2]; v31 = mem2[mem_index + 3]; i = v31; v9 = mem2[mem_index + 4]; v16 = mem2[mem_index + 5]; mem_index = (mem_index + 6) % (randomBufferSize - 6); // 32-битный эксперимент: сложение/вычитание for (int itr = 0; itr < addSubOpsCount; itr++) { v10 = (~(v11 + (v18 ^ ((v11 & (v11 + ((v11 - v18 + v10) << 8))) - v18))) - v18) | 0x337; v12 = (~(v17 + (v13 ^ ((v17 & (v17 + ((v17 - v13 + v12) << 8))) - v13))) - v13) | 0x337; v18 = (~(v11 + (v10 ^ ((v11 & (v11 + ((v11 - v10 + v18) << 8))) - v10))) - v10) | 0x1C9; v13 = (~(v17 + (v12 ^ ((v17 & (v17 + ((v17 - v12 + v13) << 8))) - v12))) - v12) | 0x1C9; v11 = (~(v10 + (v18 ^ ((v10 & (v10 + ((v10 + v11 - v18) << 8))) - v18))) - v18) | 0x2A1; v17 = (~(v12 + (v13 ^ ((v12 & (v12 + ((v12 + v17 - v13) << 8))) - v13))) - v13) | 0x2A1; } // 64-битный эксперимент: сложение/вычитание for (int itr = 0; itr < addSubOpsCount; itr++) { v14 = (~(v15 + (v8 ^ ((v15 & (v15 + ((v15 - v8 + v14) << 8))) - v8))) - v8) | 0x337; i = (~(v16 + (v9 ^ ((v16 & (v16 + ((v16 - v9 + i) << 8))) - v9))) - v9) | 0x337; v8 = (~(v15 + (v14 ^ ((v15 & (v15 + ((v15 - v14 + v8) << 8))) - v14))) - v14) | 0x1C9; v9 = (~(v16 + (i ^ ((v16 & (v16 + ((v16 - i + v9) << 8))) - i))) - i) | 0x1C9; v15 = (~(v14 + (v8 ^ ((v14 & (v14 + ((v14 + v15 - v8) << 8))) - v8))) - v8) | 0x2A1; v16 = (~(i + (v9 ^ ((i & (i + ((i + v16 - v9) << 8))) - v9))) - v9) | 0x2A1; } // 32-битный эксперимент: умножение/деление for (int itr = 0; itr < mulDivOpsCount; itr++) { v11 = v18 | (v18 * v10 * v11 * v10 * v11 / v10); v17 = v13 | (v13 * v12 * v17 * v12 * v17 / v12); } // 64-битный эксперимент: умножение/деление for (int itr = 0; itr < mulDivOpsCount; itr++) { v15 = v8 | (v8 * v14 * v15 * v14 * v15 / v14); v16 = v9 | (v9 * i * v16 * i * v16 / i); } // суммируем число всех операций за итерацию (66 - сложение/вычитание, 10 - умножение/деление) v27 += 66 * (addSubOpsCount + addSubOpsCount) + 10 * (mulDivOpsCount + mulDivOpsCount); } while (stopwatch.ElapsedMilliseconds < milliseconds); stopwatch.Stop(); /* mov rax, qword ptr cs:pfFinish xorps xmm1, xmm1 sub rax, qword ptr cs:pfStart xorps xmm2, xmm2 cvtsi2sd xmm1, qword ptr cs:stru_1402E84B8 // 10000 xorps xmm0, xmm0 mulsd xmm1, cs:qword_14018B1F8 // 1000 cvtsi2sd xmm2, rax cvtsi2sd xmm0, rsi divsd xmm2, xmm1 divsd xmm0, xmm2 divsd xmm0, cs:qword_14018B238 // 1000000 */ double result = (v27 / ((stopwatch.ElapsedMilliseconds))) / 1000.0; // выводим все значения, чтобы компилятор не срезал вычисления Console.WriteLine("Result: " + result + " | " + v11 + v17 + v4 + v10 + v12 + v13 + v18 + v15 + v16 + v14 + v8 + v9 + v31 + i); Console.ReadKey(); } } ``` ### Windows-версия (восстановлена из дизассемблера) ```csharp using System.Diagnostics; class Program { static void Main(string[] args) { long start, end; long milliseconds = 6000; // по умолчанию тест запускается на 6 секунд int randomBufferSize = 20000; // наполняем буфер 32-битных чисел для участия в тесте List<int> mem1 = new List<int>(); Random rnd1 = new Random(777); for (int n = 0; n < randomBufferSize; n++) { int a = rnd1.Next(int.MaxValue) << 17; int b = rnd1.Next(int.MaxValue); int r = a + b; mem1.Add(r == 0 ? 1 : r); } // наполняем буфер 64-битных чисел для участия в тесте List<long> mem2 = new List<long>(); Random rnd2 = new Random(777); for (int n = 0; n < randomBufferSize; n++) { long a = ((long)rnd2.Next(int.MaxValue)) << 15; long b = (a + rnd2.Next(int.MaxValue)) << 15; long c = (b + rnd2.Next(int.MaxValue)) << 15; long d = rnd2.Next(int.MaxValue); long r = c + d; mem2.Add(r == 0 ? 1 : r); } int mem_index = 0; long v27 = 0; const int addSubOpsCount = 1000; const int mulDivOpsCount = 500; int v11, v17, v4, v10, v12, v13, v18; long v15, v16, v14, v8, v9, v31, i; // Запускаем таймер для подсчета числа тиков Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); do { // параметры 32-битного эксперимента v4 = mem1[mem_index + 1]; v10 = mem1[mem_index + 0]; v11 = mem1[mem_index + 2]; v12 = mem1[mem_index + 3]; v13 = mem1[mem_index + 4]; v17 = mem1[mem_index + 5]; v18 = v4; // параметры 64-битного эксперимента v14 = mem2[mem_index + 0]; v8 = mem2[mem_index + 1]; v15 = mem2[mem_index + 2]; v31 = mem2[mem_index + 3]; i = v31; v9 = mem2[mem_index + 4]; v16 = mem2[mem_index + 5]; mem_index = (mem_index + 6) % (randomBufferSize - 6); // 32-битный эксперимент: сложение/вычитание for (int itr = 0; itr < addSubOpsCount; itr++) { v10 = (~(v11 + (v18 ^ ((v11 & (v11 + ((v11 - v18 + v10) << 8))) - v18))) - v18) | 0x337; v12 = (~(v17 + (v13 ^ ((v17 & (v17 + ((v17 - v13 + v12) << 8))) - v13))) - v13) | 0x337; v18 = (~(v11 + (v10 ^ ((v11 & (v11 + ((v11 - v10 + v18) << 8))) - v10))) - v10) | 0x1C9; v13 = (~(v17 + (v12 ^ ((v17 & (v17 + ((v17 - v12 + v13) << 8))) - v12))) - v12) | 0x1C9; v11 = (~(v10 + (v18 ^ ((v10 & (v10 + ((v10 + v11 - v18) << 8))) - v18))) - v18) | 0x2A1; v17 = (~(v12 + (v13 ^ ((v12 & (v12 + ((v12 + v17 - v13) << 8))) - v13))) - v13) | 0x2A1; } // 64-битный эксперимент: сложение/вычитание for (int itr = 0; itr < addSubOpsCount; itr++) { v14 = (~(v15 + (v8 ^ ((v15 & (v15 + ((v15 - v8 + v14) << 8))) - v8))) - v8) | 0x337; i = (~(v16 + (v9 ^ ((v16 & (v16 + ((v16 - v9 + i) << 8))) - v9))) - v9) | 0x337; v8 = (~(v15 + (v14 ^ ((v15 & (v15 + ((v15 - v14 + v8) << 8))) - v14))) - v14) | 0x1C9; v9 = (~(v16 + (i ^ ((v16 & (v16 + ((v16 - i + v9) << 8))) - i))) - i) | 0x1C9; v15 = (~(v14 + (v8 ^ ((v14 & (v14 + ((v14 + v15 - v8) << 8))) - v8))) - v8) | 0x2A1; v16 = (~(i + (v9 ^ ((i & (i + ((i + v16 - v9) << 8))) - v9))) - v9) | 0x2A1; } // 32-битный эксперимент: умножение/деление for (int itr = 0; itr < mulDivOpsCount; itr++) { v11 = v18 | (v18 * v10 * v11 * v10 * v11 / v10); v17 = v13 | (v13 * v12 * v17 * v12 * v17 / v12); } // 64-битный эксперимент: умножение/деление for (int itr = 0; itr < mulDivOpsCount; itr++) { v15 = v8 | (v8 * v14 * v15 * v14 * v15 / v14); v16 = v9 | (v9 * i * v16 * i * v16 / i); } // суммируем число всех операций за итерацию (66 - сложение/вычитание, 10 - умножение/деление) v27 += 66 * (addSubOpsCount + addSubOpsCount) + 10 * (mulDivOpsCount + mulDivOpsCount); } while (stopwatch.ElapsedMilliseconds < milliseconds); stopwatch.Stop(); /* mov rax, qword ptr cs:pfFinish xorps xmm1, xmm1 sub rax, qword ptr cs:pfStart xorps xmm2, xmm2 cvtsi2sd xmm1, qword ptr cs:stru_1402E84B8 // 10000 xorps xmm0, xmm0 mulsd xmm1, cs:qword_14018B1F8 // 1000 cvtsi2sd xmm2, rax cvtsi2sd xmm0, rsi divsd xmm2, xmm1 divsd xmm0, xmm2 divsd xmm0, cs:qword_14018B238 // 1000000 */ double result = (v27 / ((stopwatch.ElapsedMilliseconds))) / 1000.0; // выводим все значения, чтобы компилятор не срезал вычисления Console.WriteLine("Result: " + result + " | " + v11 + v17 + v4 + v10 + v12 + v13 + v18 + v15 + v16 + v14 + v8 + v9 + v31 + i); Console.ReadKey(); } } ```