0

我正在使用 cilk plus 和卸载对 Xeon phi 进行一些性能测试。

在一个简单的向量添加程序中,我有两种方法可以做到:

  1. 使用 cilk_for 将任务拆分到 Xeon phi 中的不同线程:

    __declspec(target(mic)) void vector_add(double *A,double *B,double *C,
    int  vector_size)
    {
       _Cilk_for(int i=0;i<vector_size;i++)
        {
        C[i] +=  A[i] + B[i];
        }
    }
    double *A,*B,*C;
    //allocating and initializing  A, B ,C using malloc.....
    #pragma offload target(mic:0) \
    in(B:length(vector_size)) \
    in(A:length(vector_size)) \
    in(C:length(vector_size)) \
    in(vector_size ) 
    {
      vector_add(A,B,C,vector_size);
    }
    
  2. 使用矢量注释:

    double *A,*B,*C;
    //allocating and initializing  A, B ,C using malloc.....
    #pragma offload target(mic:0) \
    in(B:length(vector_size)) \
    in(A:length(vector_size)) \
    in(C:length(vector_size))
    //in(vector_size )
    //signal(offload0)
    {
      C[0:vector_size] = A[0:vector_size]+B[0:vector_size];
    }
    

我的测试表明,第一种方式在至强 phi 上比第二种方式快约 10 倍。当我不卸载并在 Xeon E5 主机 CPU 上运行它时,也会发生同样的情况。

首先我想知道我的理解是否正确:

第一种方法仅利用 XEON phi 中的线程并行性(60 核 * 4 线程每个)。但不会执行向量运算。

第二种方法只利用向量化,它只会在一个线程中运行此代码并使用 SIMD(IMCI) 指令。

其次,我想知道编写此代码的正确方法是什么,这样它既可以将任务拆分到不同的线程,又可以在 Xeon phi 上使用向量指令?

提前致谢。

4

1 回答 1

1

实际上,如果您查看编译器生成的优化报告 (-opt-report),或者查看 VTune 输出(如果有),您可能会感到惊讶。正如您推测的那样,您的第二个示例仅矢量化。但是,除了并行化之外,您的第一个示例还可以向量化。请记住,_Cilk_for 不是分发单个迭代,而是分发在某些情况下可以向量化的迭代块。

为了更好地控制,您可以尝试使用嵌套循环来明确分离并行循环和向量循环,或者使用粒度来更改线程在任何给定时间必须处理的工作量或许多不同的 pragma。

有关专门针对英特尔至强融核协处理器进行优化的建议,我喜欢将人们指向https://software.intel.com/en-us/articles/programming-and-compiling-for-intel-many-integrated-core-架构,但我认为您可能会发现其中一些过于基础。不过,如果你想四处挖掘......

于 2015-04-14T07:58:55.373 回答