Что означают сообщения авто-векторизации gcc?

У меня есть некоторый код, который я хотел бы запустить быстро, поэтому я надеялся, что смогу убедить gcc (g ++) векторизовать некоторые из моих внутренних циклов. Флаги моего компилятора включают

-O3 -msse2 -ffast-math -ftree-vectorize -ftree-vectorizer-verbose=5

но gcc не может векторизовать наиболее важные циклы, что дает мне следующие не очень подробные сообщения:

Not vectorized: complicated access pattern.

а также

Not vectorized: unsupported use in stmt.

Мои вопросы: (1) что именно они означают? (Насколько сложным должно быть это, прежде чем оно станет слишком сложным? Неподдерживаемое использование чего именно?), И (2) есть ли способ заставить компилятор дать мне даже чуть-чуть больше информации о том, что я делаю неправильно?

Примером цикла, который дает «сложный шаблон доступа», является

for (int s=0;s<N;++s)
a.grid[s][0][h-1] =  D[s] * (b.grid[s][0][h-2] + b.grid[s][1][h-1] - 2*b.grid[s][0][h-1]);

и тот, который дает «неподдерживаемое использование в stmt», является внутренним циклом

for (int s=0;s<N;++s)
for (int i=1;i<w-1;++i)
for (int j=1;j<h-1;++j)
a.grid[s][i][j] = D[s] * (b.grid[s][i][j-1] + b.grid[s][i][j+1] + b.grid[s][i-1][j] + b.grid[s][i+1][j] - 4*b.grid[s][i][j]);

(Это то, что действительно необходимо оптимизировать.) Здесь a.grid и b.grid — трехмерные массивы с плавающей точкой, D — одномерный массив с плавающей точкой, а N, w и h — это константы.

4

Решение

Не векторизовано: сложная схема доступа.

«Неосложненные» шаблоны доступа — это последовательный доступ к элементам или доступ по элементам с определенными ограничениями (один элемент группы, к которому осуществляется доступ в цикле, количество элементов группы равно степени 2, размер группы кратен типу вектора).

b.grid[s][0][h-2] + b.grid[s][1][h-1] - 2*b.grid[s][0][h-1]);

Ни последовательный, ни поэтапный доступ

Не векторизовано: неподдерживаемое использование в stmt.

Здесь «использование» в смысле потока данных, получение значения переменной (регистр, компилятор временный). В этом случае «поддерживаемое использование» — это переменные, определенные в текущей итерации цикла, константы и инварианты цикла.

a.grid[s][i][j] = D[s] * (b.grid[s][i][j-1] + b.grid[s][i][j+1] + b.grid[s][i-1][j] + b.grid[s][i+1][j] - 4*b.grid[s][i][j]);

В этом примере, я думаю, что «неподдерживаемое использование» происходит потому, что b.grid[s][i][j-1] а также b.grid[s][i][j+1] присваиваются («определены») предыдущей итерацией цикла.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]