當使用-std=c99
,-O3
,和-mavx2
,所述 使用GCC 5.2編譯下面的代碼示例自動向量化(assembly here):如何使用GCC自動矢量化逐步寫入?
#include <stdint.h>
void test(uint32_t *restrict a,
uint32_t *restrict b) {
uint32_t *a_aligned = __builtin_assume_aligned(a, 32);
uint32_t *b_aligned = __builtin_assume_aligned(b, 32);
for (int i = 0; i < (1L << 10); i += 2) {
a_aligned[i] = 42 * b_aligned[i];
a_aligned[i+1] = 3 * a_aligned[i+1];
}
}
但下面的代碼示例不會自動矢量化(assembly here):
#include <stdint.h>
void test(uint32_t *restrict a,
uint32_t *restrict b) {
uint32_t *a_aligned = __builtin_assume_aligned(a, 32);
uint32_t *b_aligned = __builtin_assume_aligned(b, 32);
for (int i = 0; i < (1L << 10); i += 2) {
a_aligned[i] = 42 * b_aligned[i];
a_aligned[i+1] = a_aligned[i+1];
}
}
樣本之間的唯一區別是比例因子爲a_aligned[i+1]
。
對於GCC 4.8,4.9和5.1也是如此。將volatile
添加到a_aligned
的聲明完全禁止自動矢量化。第一個樣本對於我們來說一直運行得比第二個樣本快,對於較小類型的加速更加明顯(例如uint8_t
而不是uint32_t
)。
有沒有辦法讓第二個代碼示例使用GCC自動向量化?
所以唯一的區別是比例因子(3 vs沒有)?嘗試明確加1作爲縮放因子。如果解決了這個問題,這是一個編譯器錯誤。 – Jeff
或嘗試將'a_aligned [i + 1] = a_aligned [i + 1]'聲明註釋掉,或者將其重寫爲'a_aligned [i + 1] * = 1'。編譯器可能不知道如何處理您的無操作自我分配,而不是完全按照您所說的操作。 –
@Jeff確實,唯一的區別是比例因子。添加一個明確的1不會使第二個代碼示例自動向量化([assembly here](https://goo.gl/dnjSaQ))。 –