T. *_*ner 6 c performance gcc c99 vectorization
当使用-std=c99,-O3和编译GCC 5.2时,-mavx2以下代码示例自动向量化(此处为程序集):
#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];
}
}
Run Code Online (Sandbox Code Playgroud)
但是以下代码示例不会自动向量化(此处为程序集):
#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];
}
}
Run Code Online (Sandbox Code Playgroud)
样本之间的唯一区别是缩放因子a_aligned[i+1].
GCC 4.8,4.9和5.1也是如此.添加volatile到a_aligned声明会完全禁止自动矢量化.对于我们来说,第一个样本的运行速度始终高于第二个样本,对于较小的类型(例如uint8_t代替uint32_t),速度更快.
有没有办法让第二个代码示例使用GCC自动向量化?
下面的版本是矢量化的,但如果你问我的话,那就很丑了......
#include <stdint.h>
void test(uint32_t *a, uint32_t *aa,
uint32_t *restrict b) {
#pragma omp simd aligned(a,aa,b:32)
for (int i = 0; i < (1L << 10); i += 2) {
a[i] = 2 * b[i];
a[i+1] = aa[i+1];
}
}
Run Code Online (Sandbox Code Playgroud)
使用 进行编译-fopenmp和调用test(a, a, b)。