ПРАГМА выравнивания памяти 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. Но я знаю. не знаю, где точка находится.