О, сколько нам открытий чудных!  
 
   
   
 (примечание: если вы смотрели на показатель своего проца в Intel Burn Test/Lintel и мечтали - доставайте губозакатывательную машинку. На проце с лимитом 20 гигафлопс программа на паскале выдаст в районе 0.8. Ибо там - сферический конь, написанный на самом возвышенном AVX специальными людьми - а тут по одной, да ещё с гарантированной побитовой воспроизводимостью)
1. Frac() - чудовищно тормозная функция. Позорное днище на уровне Sin(). Если вы надеялись сделать ускоренный фейковый синус типа 
- Код: Выделить всё
-   function ebd_sin(a: float): float; inline;
 begin
 a:= frac(a * float(0.318309886183790671537767526745031));// 1 / 3.141592653589793));
 a:= (float(1.0) - a) * a;
 Result:= float (129600.0) * a / (float(40500.0) - a);
 end;
 - забудьте, он будет валяться в одной канаве с синусом и хрюкать они будут ноздря в ноздрю (sin() 0.04 гигафлопса, ebd_sin() 0.05).
Что в 13 раз медленнее умножения и в полтора раза медленнее, чем 1/sqrt(x).
2. В 64-битном коде некоторые вещи сильно медленнее, а некоторые сильно быстрее - но воспроизводимость при этом идеальная. Контрольные суммы всегда сходятся с таковыми от 32-битного кода. Чтобы не сошлись - надо лезть в ассемблер и руками тянуться в розетку RSQRTPS (быстрый и грязный обратный квадратный корень). Вот та - да, у той на каждом процессоре контрольная сумма будет иная.
ЕМНИП, на Cortex A7 контрольные суммы были абсолютно такими же - хотя казалось бы. Не могу сейчас проверить, все мои малины и апельсины пылятся на полке. И тем более не могу проверить арм 64: у меня таких просто нет. Купил в прошлом году апельсин - думал, чё так дёшево. Оказалось - внутри всё тот же Cortex A7 в обнимку с Mali 400. То есть, Orange Pi PC - это китайский аналог Raspberry Pi 2B, не выше. А в продаже всё ещё есть!
Как бы то ни было, на x86-64:
 - Frac() ускорилась ровно в три раза, благодаря чему ebd_sin() обогнал Sin() в 3.4 раза - поскольку тот *ещё* замедлился, до 0.035 гигафлопса. У них специальное соревнование, штоле?
 - умножение на константу, не завёрнутую в тайпкаст ко флоату, замедлилось в 2.78 раза по сравнению с завёрнутой. Причём, контрольные суммы что того, что другого варианта - сходятся со своими аналогами из 32-битного кода (а между собой они разные). 
Подробнее (включая исходник теста) - когда починю свой сервер и будет, куда выложить.
Добавлено спустя 21 час 10 минут 8 секунд:Развивая тему скорости: SQRTPS + DIVPS заранее загруженными в регистры единицами *ровно* в четыре раза быстрее штатного 1/ sqrt(x). Очевидно, компилятор использует абсолютно те же команды - только скалярные, а не векторные. Во за счёт четырёх операций за раз - и ускорение ровно в четыре раза. У меня там закоментирована RCPPS - очевидно, контрольная сумма не сошлась, побитово получимлось не так, как честное 1/x посредством DIVPS.
Но вы посмотрите, как жж
от RSQRTPS (в четыре с половиной раза быстрее воспроизводимого sse и в восемнадцать раз - штатного 1/ sqrt(x)) - и становится очевидно, что это не компилятор плохой, это процессор задумчивый, когда от него требуют побитового соответствия стандартам. 
    ..checking 1/sqrt(x)
      .................................
      ..ok, in 45 (pure 21,2) seconds (0,1 GFLOPS)
      ..md5 checksum = 7BA70F1439D5E2955151CC565477E924
    ..checking SSE SIMD4 1/sqrt(x)
      .................................
      ..ok, in 29 (pure 5,31) seconds (0,401 GFLOPS)
      ..md5 checksum = 7BA70F1439D5E2955151CC565477E924
    ..checking SSE SIMD4 RSQRTPS (packed quick reverse square root)
      .................................
      ..ok, in 25 (pure 1,18) seconds (1,81 GFLOPS)
      ..md5 checksum = F881C03FB2C6F5BBDFF57AE5532CFFFD
Напомню, это на камне, для которого Lintel репорртует 20 гигафлопс на одно ядро (и 30 на два, ибо оба на форсаже не укладываются в TDP).
Добавлено спустя 3 минуты 45 секунд:- Код: Выделить всё
-           dck_one_div_sqrt: begin
 for m:= 0 to (mm div 8) - 1  do begin
 pointer(pv):= p + m * 8 * sizeof(float);
 pv[0]:= 1/sqrt(pv[0]);
 pv[1]:= 1/sqrt(pv[1]);
 pv[2]:= 1/sqrt(pv[2]);
 pv[3]:= 1/sqrt(pv[3]);
 pv[4]:= 1/sqrt(pv[4]);
 pv[5]:= 1/sqrt(pv[5]);
 pv[6]:= 1/sqrt(pv[6]);
 pv[7]:= 1/sqrt(pv[7]);
 end;
 end;
 {$if defined(cpu386)}
 dck_sse_one_div_sqrt: begin
 for m:= 0 to (mm div 8) - 1  do begin
 pointer(pv):= p + m * 8 * sizeof(float);
 asm
 mov eax, [fourones]
 MOVAPS xmm5, [eax]
 mov eax, [pv]
 MOVAPS xmm6, [eax]
 SQRTPS xmm6, xmm6
 MOVAPS xmm4, xmm5
 DIVPS xmm4, xmm6 //RCPPS   xmm6, xmm6 //Reciprocal Parallel Scalars or, simply speaking, 1.0/x
 MOVAPS xmm7, [eax + 16]
 SQRTPS xmm7, xmm7
 MOVAPS [eax], xmm4
 DIVPS xmm5, xmm7 //RCPSS xmm7, xmm7
 MOVAPS [eax + 16], xmm5
 end['eax', 'xmm6', 'xmm7', 'xmm4', 'xmm5'];
 end;
 end;
 dck_sse_rsqrtps: begin
 for m:= 0 to (mm div 8) - 1  do begin
 pointer(pv):= p + m * 8 * sizeof(float);
 asm
 mov eax, [pv]
 MOVAPS xmm6, [eax]
 RSQRTPS xmm6, xmm6
 MOVAPS xmm7, [eax + 16]
 RSQRTPS xmm7, xmm7
 MOVAPS [eax], xmm6
 MOVAPS [eax + 16], xmm7
 end['eax', 'xmm6', 'xmm7'];
 end;
 end;
 {$endif}
, где mm в подавляющем большинстве случаев = 2048