Я тестирую разные формы умножения матриц с разными уровнями оптимизации (в учебных целях), и я обнаружил странное поведение в gve autovectorization. Он не может векторизовать, когда массивы являются параметрами (см. Mxmp), но способен векторизовать, когда массивы являются глобальными переменными (см. Mxmg)
gcc версия 7.4.0 (Ubuntu 7.4.0-1ubuntu1 ~ 18.04.1)
но поведение было прежним со старыми версиями gcc
Варианты компиляции:
gcc -O3 -mavx2 -mfma
#define N 1024
float A[N][N], B[N][N], C[N][N];
void mxmp(float A[N][N], float B[N][N], float C[N][N]) {
int i,j,k;
for (i=0; i<N; i++)
for (j=0; j<N; j++)
for (k=0; k<N; k++)
C[i][j] = C[i][j] + A[i][k] * B[k][j];
}
void mxmg() {
int i,j,k;
for (i=0; i<N; i++)
for (j=0; j<N; j++)
for (k=0; k<N; k++)
C[i][j] = C[i][j] + A[i][k] * B[k][j];
}
main(){
mxmg();
mxmp(A, B, C);
}
Я ожидал, что компилятор сделает то же самое в обеих функциях, однако mxmp требует примерно в 10 раз больше времени выполнения mxmg. Изучая код ассемблера, просто случается, что gcc способен автоматически векторизовать mxmg (когда массивы являются глобальными переменными), но не может векторизовать mxmp (где массивы являются параметрами).
Пробовал то же самое с формой kij, и он может векторизовать обе функции.
Мне нужна помощь, чтобы выяснить, почему у gcc такое поведение. И как помочь gcc (прагмы, параметры компиляции, атрибуты, ...) правильно векторизовать функцию mxmp.
Спасибо