Мой ноутбук поддерживает только AVX (расширенное расширение векторов), но не поддерживает AVX2. Для AVX 128-битные xmm * регистры уже были расширены до 256-битных регистров ymm * для арифметики с плавающей запятой. Тем не менее, я тестировал, что все версии Visual Studio (с 2010 по 2015 год) не используют ymm * регистры под/arch: оптимизация AVX, хотя они делают это под/arch: оптимизация AVX2.Visual Studio 2010 - 2015 не использует регистры ymm * для оптимизации AVX
Ниже приведена разборка для простого цикла. Программа скомпилирована с/arch: AVX в сборке релизов, причем все параметры оптимизации включены.
float a[10000], b[10000], c[10000];
for (int x = 0; x < 10000; x++)
1000988F xor eax,eax
10009891 mov dword ptr [ebp-9C8Ch],ecx
c[x] = (a[x] + b[x])*b[x];
10009897 vmovups xmm1,xmmword ptr c[eax]
100098A0 vaddps xmm0,xmm1,xmmword ptr c[eax]
100098A9 vmulps xmm0,xmm0,xmm1
100098AD vmovups xmmword ptr c[eax],xmm0
100098B6 vmovups xmm1,xmmword ptr [ebp+eax-9C78h]
100098BF vaddps xmm0,xmm1,xmmword ptr [ebp+eax-9C78h]
100098C8 vmulps xmm0,xmm0,xmm1
100098CC vmovups xmmword ptr [ebp+eax-9C78h],xmm0
100098D5 add eax,20h
100098D8 cmp eax,9C40h
100098DD jl ComputeTempo+67h (10009897h)
const int winpts = (int)(window_size*sr+0.5);
100098DF vxorps xmm1,xmm1,xmm1
100098E3 vcvtsi2ss xmm1,xmm1,ecx
Я также проверил, что я могу использовать регистры ymm * для дальнейшего ускорения моей программы без сбоев. Я сделал это с использованием IMM-функций, например. _mm256_mul_ps.
Может ли разработчик компилятора Microsoft дать объяснение? Или, может быть, это одна из причин, почему Visual Studio дает более медленные коды, чем компилятор gcc/g ++?
Пробовал ли цикл, где компилятор знает, что массивы выровнены по 32B? Я замечаю, что он использует нестандартные команды загрузки/хранения. Кроме того, процессоры AMD хуже с 256-битным AVX-кодом, чем с 128-битным AVX-кодом, особенно. Piledriver имеет огромные проблемы с 256b магазинами. Поэтому, если вы не сказали компилятору оптимизировать для конкретной микроархитектуры, векторы 128b «более безопасны». –
Я тестировал void 'void foo (float * a, float * b, float * c) {for (int i = 0; i <10000; i ++) c [i] = (a [i] + b [i]) * б [I]; } 'в MSVC 2015 с' cl/c/O2/arch: AVX' и использует 'ymm'. Я не знаю, в чем проблема. –
@PeterCordes, нет никакого штрафа за использование нестандартных инструкций загрузки с AVX. Существует штраф (но не большой) для того, чтобы память не была выровнена на 32B, но Clang и MSVC не настраиваются для этого (но GCC и ICC делают). –