我正在尝试将矢量化检查为一个简单的循环。我正在 MacOS 19.5 上工作,我的代码是用 gcc-mp-4.9 编译的(从 Macports 安装)。为了通过矢量化获得更好的性能,我测量了主循环所花费的时间,并将其与非矢量化版本进行比较。
这是这个简单的代码(我使用 "NOVEC"
或 "VEC"-D flag
编译):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 1000000000
#ifdef NOVEC
void addition_tab_novec(double *a, double *b, double *c)
{
int i;
for (i=0; i<SIZE; i++)
c[i] = a[i] + b[i];
}
#endif
#ifdef VEC
void addition_tab_vec(double * restrict a, double * restrict b, double * restrict c)
{
int i;
double *x = __builtin_assume_aligned(a, 16);
double *y = __builtin_assume_aligned(b, 16);
double *z = __builtin_assume_aligned(c, 16);
for (i=0; i<SIZE; i++)
z[i] = x[i] + y[i];
}
#endif
int main(int argc, char *argv[])
{
// Array index
int i;
// Two input arrays
double *tab_x;
double *tab_y;
double *tab_z;
// Time elapsed
time_t time1, time2;
// Allocation
tab_x = (double*) malloc(SIZE*sizeof(double));
tab_y = (double*) malloc(SIZE*sizeof(double));
tab_z = (double*) malloc(SIZE*sizeof(double));
// Initialization
for (i=0; i<SIZE; i++)
{
tab_x[i] = i;
tab_y[i] = 2*i;
tab_z[i] = 0.0;
}
#ifdef NOVEC
// Start time for vectorization
time(&time1);
// Addition function
addition_tab_novec(tab_x, tab_y, tab_z);
// Compute elapsed time for vectorization
time(&time2);
printf("No Vectorization - Time elapsed = %f seconds\n", difftime(time2, time1));
#endif
#ifdef VEC
// Start time for vectorization
time(&time1);
// Addition function
addition_tab_vec(tab_x, tab_y, tab_z);
// Compute elapsed time for vectorization
time(&time2);
printf("Vectorization - Time elapsed = %f seconds\n", difftime(time2, time1));
#endif
return 0;
}
我的问题是,与非矢量化版本相比,矢量化没有获得更好的结果。
鉴于我使用“__builtin_assume_aligned(array, 16)
”,即 16 字节对齐
,我希望在测量循环中获得两倍的运行时间(我使用 double 组 sizeof(double) = 8 bytes
)
但实际上,在没有矢量化的情况下我得到了 60 秒,而在矢量化情况下我得到了 59 秒:我如何解释这些相同的结果?
以下是两种情况下的编译命令行:
无矢量化:
gcc-mp-4.9 -DNOVEC -std=c99 -fno-tree-vectorize main_benchmark.c
矢量化:
gcc-mp-4.9 -DVEC -std=c99 -Wa,-q -O3 -march=native -ftree-vectorize -fopt-info-vec main_benchmark.c
我不确定是否未针对非矢量化编译激活优化。如果是这种情况,如何禁用它?
感谢您的帮助
最佳答案
看看汇编代码会很有趣。
通常情况下,您最多可以期望两倍的性能,但在这种情况下,考虑到数组的大小,您不会接近这个值,CPU 只是闲置,等待数据被提取到并在它执行任何操作之前从缓存中清除,这可能就是没有增益的原因。
处理大量数据时,还可能涉及内存管理开销,因此最好锁定内存,请参阅 mlock
联机帮助页。
关于使用 gcc-4.9 将矢量化检查为简单示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39564073/