Я рассматриваю простую проблему - ускоряя вычисление компонентного продукта двух массивов двойников. Я заметил, что с помощью команд AVX я получаю только около 20% ускорения, по сравнению с последовательным умножением в цикле.Код сборки Intel intrinsics
Я решил проверить латентность для обоих случаев и путался с ассемблере операции загрузки:
### __m256d pd;
### pd = _mm256_load_pd(a);
movq -112(%rbp), %rax //Pushing the pointer to the stack
vmovapd (%rax), %ymm0 //Pushing 32 bytes from memory to ymm
vmovapd %ymm0, -80(%rbp) //What is
vmovapd -80(%rbp), %ymm0 //happening here?
vmovapd %ymm0, -48(%rbp) //Quite slow down, since vmovapd cost ~ vmulpd
Над частью сборки для следующего кода C:
inline int test(double * a) {
__m256d pd;
pd = _mm256_load_pd(a);
return 1;
}
в описании __m256_load_pd говорят, что это делается таким образом:
dst[255:0] := MEM[mem_addr+255:mem_addr]
dst[MAX:256] := 0
т. Е. В обратном порядке? Но как эти 2 строки кода сборки должны что-то сделать с этим?
Вы компилируете с отключенной оптимизацией, поэтому gcc делает медленный код braindead. С оптимизацией 'test()' компилируется только в 'return 1', потому что' pd' никогда не используется. Если 20% ускорение с '-O0', то попробуйте с' -O3'. Вы должны включить оптимизацию, если хотите, чтобы код работал быстро. –
Синтаксис AT & T использует 'op src2, src1, dest' с'% 'декораторами в именах регистров, тогда как синтаксис Intel использует' op dest, src1, src2'. Псевдокод руководства Intel не является asm вообще, он просто описывает операцию. –
20% ускорение - результат для флага -O3 с icpc. – Tzoiker