Краткий ответ: Это сбой компилятора. Ошибка оптимизатора x64.
Длинный ответ:
Эта версия x86 очень медленная, если SSE2 отключен. Но я могу воспроизвести результаты с включенным SSE2 в x86.
Если вы погрузитесь в сборку этого самого внутреннего цикла. Версия x64 имеет две дополнительные копии памяти в конце.
x86:
$LL71@main:
movsd xmm2, QWORD PTR [eax-8]
movsd xmm0, QWORD PTR [eax-16]
movsd xmm3, QWORD PTR [eax]
movapd xmm1, xmm0
mulsd xmm0, QWORD PTR __real@3fa60418a0000000
movapd xmm7, xmm2
mulsd xmm2, QWORD PTR __real@3f95810620000000
mulsd xmm7, xmm5
mulsd xmm1, xmm4
addsd xmm1, xmm7
movapd xmm7, xmm3
mulsd xmm3, QWORD PTR __real@3fdcccccc0000000
mulsd xmm7, xmm6
add eax, 24 ; 00000018H
addsd xmm1, xmm7
addsd xmm0, xmm2
movq QWORD PTR [ecx], xmm1
addsd xmm0, xmm3
movq QWORD PTR [ecx+8], xmm0
lea edx, DWORD PTR [eax-16]
add ecx, 16 ; 00000010H
cmp edx, esi
jne SHORT $LL71@main
64
$LL175@main:
movsdx xmm3, QWORD PTR [rdx-8]
movsdx xmm5, QWORD PTR [rdx-16]
movsdx xmm4, QWORD PTR [rdx]
movapd xmm2, xmm3
mulsd xmm2, xmm6
movapd xmm0, xmm5
mulsd xmm0, xmm7
addsd xmm2, xmm0
movapd xmm1, xmm4
mulsd xmm1, xmm8
addsd xmm2, xmm1
movsdx QWORD PTR r$109492[rsp], xmm2
mulsd xmm5, xmm9
mulsd xmm3, xmm10
addsd xmm5, xmm3
mulsd xmm4, xmm11
addsd xmm5, xmm4
movsdx QWORD PTR r$109492[rsp+8], xmm5
mov rcx, QWORD PTR r$109492[rsp]
mov QWORD PTR [rax], rcx
mov rcx, QWORD PTR r$109492[rsp+8]
mov QWORD PTR [rax+8], rcx
add rax, 16
add rdx, 24
lea rcx, QWORD PTR [rdx-16]
cmp rcx, rbx
jne SHORT $LL175@main
В версии x64 гораздо больше (необъяснимых) ходов в конце цикла. Это выглядит как некая копия данных из памяти в память.
EDIT:
Оказывается, что оптимизатор x64 не может оптимизировать следующую копию:
(*i2) = r;
Вот почему во внутреннем цикле есть две дополнительные копии памяти. Если вы измените цикл следующим образом:
std::for_each(m.begin(), m.end(),
[&](const Vector& v)
{
i2->x = Dot(axisX, v);
i2->y = Dot(axisY, v);
++i2;
});
Это исключает копии. Теперь версия x64 работает так же быстро, как и версия x86:
x86: 0.0249423
x64: 0.0249348
Извлеченный урок: Компиляторы не идеальны.