使用 gcc-4.9 将矢量化检查为简单示例

标签 c gcc vectorization

我正在尝试将矢量化检查为一个简单的循环。我正在 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/

相关文章:

mysql - 绑定(bind)的C mysql准备语句问题

c - fgets 返回段错误 - 读入文件 C

c - 用 C 读取高分/分析字符串

c - 从 Ubuntu 20.04 更新后,Ubuntu 22.04 上出现 gcc "multiple definition of "错误

c++ - 两个矩阵的C++高效按元素匹配

c - 河豚浮点

c - 错误: cannot use an address to initialize a field of a packed struct (#pragma pack)

c - 使用 __attribute__ ((section "STACK")) 将变量准确地放在 ("STACK"部分中可能有什么意义?

MATLAB 基于长度向量的重复数

python - 在 Python 中查找重复矩阵?