3

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

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

该代码基本上由两个几乎相同的代码块组成,它们使用 OpenMP 使用 4 个线程计算答案。唯一的区别是,在第二个 块中,我使用向量化函数__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;
}
4

0 回答 0