为什么我的OpenMP simd指令没有任何用处?

时间:2017-06-08 08:42:38

标签: openmp simd

我已经尝试过这些代码来测试OpenMP中的SIMD指令。

#include <iostream>
#include <sys/time.h>
#include <cmath>
#define N 4096
#define M 1000
using namespace std;

int main()
{
    timeval start,end;
    float a[N],b[N];
    for(int i=0;i<N;i++)
        b[i]=i;
    gettimeofday(&start,NULL);
    for(int j=0;j<M;j++)
    {
    #pragma omp simd 
        for(int i=0;i<N;i++)
            a[i]=pow(b[i],2.1);
    }
    gettimeofday(&end,NULL);
    int time_used=1000000*(end.tv_sec-start.tv_sec)+(end.tv_usec-start.tv_usec);
    cout<<"time_used="<<time_used<<endl;
    return 1;
}

但要么是我用

编译的
g++ -fopenmp simd.cpp

g++ simd.cpp

他们对“time_used”的报告几乎是一样的。看起来我使用的SIMD指令没有任何用处? 谢谢!

其他问题: 我换了

a[i]=pow(b[i],2.1);

通过

a[i]=b[i]+2.1;

当我按

编译它们时
g++ -fopenmp simd.cpp

“time_used”的输出大约是12000。 当我按

编译它们时
g++ simd.cpp

“time_used”的输出大约是12000,几乎和以前一样。

我的电脑:Haswell i5,8g内存,ubuntu kylin 16.04,gcc 5.4.0

1 个答案:

答案 0 :(得分:1)

编译器无法自动向量化函数调用。它只能矢量化可以使用SIMD指令完成的特定算术运算。

因此,您需要一个使用SIMD指令实现pow函数的矢量数学库。 Intel provides one。我不确定pow是否是向量优化提供的功能之一,但我想是的。您还应该注意,英特尔的数学库可能不是AMD处理器的最佳选择。

You claim您尝试将pow函数调用更改为简单添加,但未看到结果有任何改进。我不太确定这是怎么可能的,因为如果你改变内循环:

a[i]=pow(b[i],2.1);

,说:

a[i] += b[i];

或:

a[i] += (b[i] * 2);

然后GCC, with optimizations enabled, notices that you never use the result and elides the entire thing。它无法使用pow函数调用执行此优化,因为它不知道函数是否有任何其他副作用。但是,对于优化器可见的代码,它可以......好吧,优化它。在某些情况下,它可能能够对其进行矢量化。在这种情况下,它可以完全删除它。

如果您尝试了优化程序完全删除此循环的代码,并且您仍然没有看到基准测试得分的改进,那么显然这不是代码中的瓶颈而您不必担心试图对其进行矢量化。