Compiler construction 有没有办法在AMD OpenCL内核中使用编译器展开循环?

Compiler construction 有没有办法在AMD OpenCL内核中使用编译器展开循环?,compiler-construction,opencl,pragma,loop-unrolling,amd-processor,Compiler Construction,Opencl,Pragma,Loop Unrolling,Amd Processor,我试图评估OpenCL for AMD和Nvidia GPU之间的性能差异。我有一个执行矩阵向量乘法的内核。目前我正在两个不同的系统上运行内核,我的笔记本电脑有一个NVidia GT525m和Ubuntu 12.04以及CUDA 4.0(其中包含OpenCL库和头文件),另一个是一个台式机,同样有AMD Radeon HD7970和Ubuntu 12.04以及最新的Catalyst驱动程序 在内核中,我有两个代码> > PraceMun-OrLoo/语句,这些语句为英伟达OpenCL实现(~6x

我试图评估OpenCL for AMD和Nvidia GPU之间的性能差异。我有一个执行矩阵向量乘法的内核。目前我正在两个不同的系统上运行内核,我的笔记本电脑有一个NVidia GT525m和Ubuntu 12.04以及CUDA 4.0(其中包含OpenCL库和头文件),另一个是一个台式机,同样有AMD Radeon HD7970和Ubuntu 12.04以及最新的Catalyst驱动程序

在内核中,我有两个代码> > PraceMun-OrLoo/<代码>语句,这些语句为英伟达OpenCL实现(~6x)产生了很大的加速。但是AMD OpenCL版本不会产生任何加速。使用AMD应用程序内核分析器查看内核时,会出现一个错误,即未使用展开,因为行程计数未知。 所以我的问题是,

#pragma unroll
是否与AMD OpenCL一起工作,或者是否有其他选择(可能是我不知道的编译器标志)。我已经在下面介绍了内核

__kernel void mvKernel(__global float* a, const __global float* x, __global float* y, int m, int n)
{
    float sum = 0.0f;
    __global float* A;
    int i;
    int j = 0;
    int indx = get_global_id(0);
    __local float xs[12000];
#pragma unroll 
    for(i = get_local_id(0); i < n; i+= get_local_size(0)) {
        xs[i] = x[i];
    } 
    barrier(CLK_LOCAL_MEM_FENCE);
    A = &a[indx];
#pragma unroll 256
    for(i = 0; i < n; i++) {
        sum += xs[i] * A[j];
        j += m;
    }
    y[indx] = sum;
}
\uuuu内核void mvKernel(\uuuu全局浮点*a,const\uuu全局浮点*x,\uuu全局浮点*y,int m,int n)
{
浮动总和=0.0f;
__全球浮动*A;
int i;
int j=0;
int indx=获取全局id(0);
__本地浮动xs[12000];
#布拉格展开
对于(i=get_local_id(0);i

同一个内核在两种实现中都会产生正确的结果,但是#pragma unroll命令对AMD没有任何作用(通过注释它们来检查)。

没有文档记录,但它实际上应该与
#pragma unroll
一起工作。您可以检查编译器日志以查看是否应用了展开吗?我不确定内核分析器是否使用与OpenCL运行时相同的编译器,您可能需要检查

否则,如果您知道
n
以256块的形式出现,您可以手动展开,方法是在256个元素的块上有一个循环,在其中有一个固定大小为256的循环,这可能更容易展开。这肯定会解决静态不知道跳闸计数的问题


但是,请记住,展开循环通常不会带来太大的成功,因为您没有太多的寄存器来缓存您的计算。回路展开导致的寄存器压力增加可能会导致寄存器溢出,甚至更慢。您应该检查AMD卡上内核的实际速度。一个更新的英伟达OpenCL编译器可能也不会从unLoad Prima.< /P>中获益。我目前还没有访问AMD机器,但从我可以记得的是,内核在AMD卡上使用3.0MS,有或没有ORD,而NVIDIA用unRoad占用0.7Ms,不展开时大约1.17ms,如果我使用标志“-cl opt disable”编译内核时2.88ms,这将关闭所有编译器优化,因此看起来很多速度的提高实际上并不是来自展开。明天我将查看编译器日志,看看它给出了什么。正在应用展开,我想我只需要为AMD架构优化我的代码。展开会导致代码大小扩大,从而导致I-cache未命中。但它如何导致寄存器压力增加?我没听懂。我的意思是寄存器的活动范围不会因为循环被展开而改变。我猜想,如果稍后的编译器优化过程执行一些与活动区域重叠的代码运动,那么活动的同时寄存器的数量可能会增加。这就是你的意思吗?但您可能认为编译器在执行代码运动时会跟踪这一点,以避免溢出填充。它可以展开,然后尝试向前移动加载,这会增加寄存器压力。