ПРАГМА выравнивания памяти gcc

у gcc есть ПРАГМА выравнивания памяти, akin #pragma vector aligned в компиляторе Intel? Я хотел бы сказать компилятору оптимизировать определенный цикл, используя выровненные инструкции loads / store. чтобы избежать возможной путаницы, речь идет не о структуре упаковки.

Эл.г:

#if defined (__INTEL_COMPILER)
#pragma vector aligned
#endif
        for (int a = 0; a < int(N); ++a) {
            q10 += Ix(a,0,0)*Iy(a,1,1)*Iz(a,0,0);
            q11 += Ix(a,0,0)*Iy(a,0,1)*Iz(a,1,0);
            q12 += Ix(a,0,0)*Iy(a,0,0)*Iz(a,0,1);
            q13 += Ix(a,1,0)*Iy(a,0,0)*Iz(a,0,1);
            q14 += Ix(a,0,0)*Iy(a,1,0)*Iz(a,0,1);
            q15 += Ix(a,0,0)*Iy(a,0,0)*Iz(a,1,1);
        }

спасибо

3 ответов


от http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html

typedef double aligned_double __attribute__((aligned (16)));
// Note: sizeof(aligned_double) is 8, not 16
void some_function(aligned_double *x, aligned_double *y, int n)
{
    for (int i = 0; i < n; ++i) {
        // math!
    }
}

Это не aligned_double 16 байт в ширину. Это просто сделает его выровненным по 16-байтовой границе,или, скорее, первым в массиве. Глядя на разборку на моем компьютере, как только я использую директиву выравнивания, я начинаю видеть много векторных операций. На данный момент я использую компьютер с архитектурой Power, поэтому это код altivec, но я думаю, что это делает то, что вы хотеть.

(примечание: Я не использовал double когда я тестировал это, потому что altivec не поддерживает двойные поплавки.)

вы можете увидеть некоторые другие примеры автовекторизации, используя атрибуты типа здесь:http://gcc.gnu.org/projects/tree-ssa/vectorization.html


Я попробовал ваше решение с G++ версии 4.5.2 (как Ubuntu, так и Windows) и он сделал не векторизовать цикл.

Если атрибут выравнивания удаляются, то это vectorizes петли, используя нагрузки сама по себе.

Если функция встроена так, что массив может быть доступен непосредственно с устраненным указателем, то он векторизуется с выровненными нагрузками.

в обоих случаях атрибут выравнивания мешает векторизации. Это иронично: "aligned_double *x" должен был включить векторизацию, но он делает обратное.

какой компилятор сообщил вам о векторизованных циклах? Я подозреваю, что это не компилятор gcc?


имеет ли gcc выравнивание памяти pragma, akin #Pragma Vector aligned

похоже, что более новые версии GCC имеют __builtin_assume_aligned:

встроенные функции: void * __builtin_assume_aligned (const void *exp, size_t align, ...)

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

void *x = __builtin_assume_aligned (arg, 16);

означает, что компилятор может предположить, что x, установленный в arg, выровнен по крайней мере на 16 байт, в то время как:

void *x = __builtin_assume_aligned (arg, 32, 8);

означает, что компилятор может предположить для x, заданного в arg, что (char *) x - 8 выровнен по 32 байтам.

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