我是 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;
}