为什么Xeon Phi上的简单Riemann和积分的向量化还原的时间如此糟糕?

时间:2014-01-31 01:35:11

标签: performance intel-mic

我是Xeon Phi的新手,因此我正在阅读手册以了解如何操作 使用向量寄存器提高Phi的性能。

考虑这个问题末尾的短代码,它使用黎曼和计算[0,1]上曲线4 /(1 + x ^ 2)下的面积。分析答案是pi = 3.14159 ....

代码基本上由两个使用OpenMP的 几乎相同的 代码块组成 使用4个线程计算答案。唯一的区别是第二 chunk我使用向量化函数__sec_reduce_add()来计算黎曼 给予线程的[0,1]子域的总和。

第一个代码块的时间是0.0866439 s,而第二个(向量化的)块的时间是0.0868771 s

为什么这两者都会产生几乎相同的时间。我会想到使用矢量 注册会显着提高性能。

我用icc -mmic -vec-report3 -openmp标志

编译了这个

[注意:我在两个部分放了一个带有rpt变量的for循环,因为rpt = 0和rpt = 1是“预热”循环,因此会有更高的时间。我已经在rpt = 3]

给出了两个部分的时间
#include <iostream>
#include <omp.h>
using namespace std;

int main (void)
{
  int num_steps     = 2e8           ;
  double dx        = 1.0/num_steps ;
  double x         = 0.            ;
  double* fn = new double[num_steps];

  // Initialize an array containing function values
  for(int i=0 ; i<num_steps ;++i )
    {
      fn[i] = 4.0*dx/(1.0 + x*x);
      x += dx;
    }


for(size_t rpt=0 ; rpt<4 ; ++rpt)
{
  double start = omp_get_wtime();
  double parallel_sum = 0.;
  #pragma omp parallel num_threads(4)
  {
    int threadIdx = omp_get_thread_num();
    int begin = threadIdx * num_steps/4 ; //integer index of left-end  point of sub-interval
    int end   = begin + num_steps/4     ;// integer index of right-end point of sub-interval
    double dx_local = dx                ;
    double temp = 0                     ;
    double x    = begin*dx              ;

    for (int i = begin; i < end; ++i)
      {
        temp += fn[i];
      }
    #pragma omp atomic
    parallel_sum += temp;
  }
  double end   = omp_get_wtime();
  std::cout << "\nTime taken for the parallel computation: "    << end-start << " seconds";


  //%%%%%%%%%%%%%%%%%%%%%%%%%

  start = omp_get_wtime();
  double parallel_vector_sum = 0.;
  #pragma omp parallel num_threads(4)
  {
    int threadIdx = omp_get_thread_num();
    int begin = threadIdx * num_steps/4 ; //integer index of left-end  point of sub-interval
    int end   = begin + num_steps/4     ;// integer index of right-end point of sub-interval
    double dx_local = dx                ;
    double temp = 0                     ;
    double x    = begin*dx              ;

    temp = __sec_reduce_add( fn[begin:end-begin+1]   );
    #pragma omp atomic
      parallel_vector_sum += temp;
  }
  end   = omp_get_wtime();
  std::cout << "Time taken for the parallel vector computation: "    << end-start << " seconds"  ;


 }// end for rpt
  return 0;
}

0 个答案:

没有答案