Оптимизация кода SSE GCC

Этот пост тесно связан с другим постом, который я опубликовал несколько дней назад . На этот раз я написал простой код, который просто добавляет пару массивов элементов, умножает результат на значения в другом массиве и сохраняет его в четвертом массиве, все переменные с плавающей запятой с двойной точностью.

Я сделал две версии этого кода: одну с инструкциями SSE, используя вызовы, и другую без них. Затем я скомпилировал их с уровнем оптимизации gcc и -O0. Я пишу их ниже:

// SSE VERSION

#define N 10000
#define NTIMES 100000
#include 
#include 
#include 
#include 

double a[N] __attribute__((aligned(16)));
double b[N] __attribute__((aligned(16)));
double c[N] __attribute__((aligned(16)));
double r[N] __attribute__((aligned(16)));

int main(void){
  int i, times;
  for( times = 0; times < NTIMES; times++ ){
     for( i = 0; i 

При компиляции с -O0, gcc использует регистры XMM / MMX и инструкции SSE, если специально не заданы параметры -mno-sse (и другие). Я проверил ассемблерный код, сгенерированный для второго кода, и заметил, что он использует инструкции movsd , addd и mulsd . Таким образом, он использует инструкции SSE, но только те, которые используют младшую часть регистров, если я не ошибаюсь. Ассемблерный код, сгенерированный для первого кода C, как и ожидалось, использовал инструкции addp и mulpd , хотя был сгенерирован гораздо больший ассемблерный код.

В любом случае, первый код должен получить больше пользы, насколько мне известно, от парадигмы SIMD, поскольку на каждой итерации вычисляются два результирующих значения.Тем не менее, второй код выполняет что-то вроде на 25 процентов быстрее, чем первый. Я также провел тест со значениями одинарной точности и получил аналогичные результаты. В чем причина этого?

14
задан Community 23 May 2017 в 12:25
поделиться