OpenCL内核在更快的GPU上执行速度更慢

时间:2012-01-25 13:08:54

标签: performance optimization opencl gpu nvidia

我是OpenCL的新手,并且一直在尝试实现DSP算法 比较它在不同GPU上的性能与标准CPU实现的比较。 虽然我已经取得了巨大的性能提升,但我发现奇怪的是我在GT240上得到的速度与速度更快的GTX 480几乎相同。我的程序执行两个内核,而一个加速GTX 480,另一个减速下来。

GT240:内核1:226us,内核2:103us。

GTX 480:内核1:35us,内核2:293us。

这些数字是使用Visual Profiler获得的。 下面是内核2的代码,它在较大的卡上几乎慢了3倍。这个内核需要一块大的iTotalBins x iNumAngles内存块,并计算每行iNumAngles长度的最大值,并将曲线拟合到3个相邻的值。

__kernel void max_curve_fit_gpu (__global float* fCorrelationResult,
                          const int iNumAngles,
                          const int iTotalBins,
                          __global float* fResult){

// Get the thread ID which is used as the index the bin the direction is being calculated for
const int iBinNum = get_global_id(0);
const int iOffset = iBinNum*iNumAngles;

// Find the max for this bin
float fMax = 0;
int iMaxIndex = 0;
for (int iAngle=0; iAngle<iNumAngles; iAngle++)
{
    if (fMax < fCorrelationResult[iOffset + iAngle])
    {
        fMax = fCorrelationResult[iOffset + iAngle];
        iMaxIndex = iAngle;
    }
}

// Do the curve fit
float fPrev, fNext, fA, fB, fAxis;
fPrev = fCorrelationResult[iOffset + (iMaxIndex + iNumAngles - 1) % iNumAngles];
fNext = fCorrelationResult[iOffset + (iMaxIndex + iNumAngles + 1) % iNumAngles];

fB = (fPrev - fNext)*0.5f;
fA = (fNext + fPrev) - fMax*2.0f;
fAxis = fB / fA;

    // Store the result
fResult[iBinNum] = iMaxIndex + fAxis; }

Visual Profiler还表明内核2有135%的全局内存指令重放。我有一个版本的max search,它不使用if-else语句,但它在两个GPU上的运行速度都更慢。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:3)

在您的代码中,线程T将访问fCorrelationResult[T*iNumAngles+iAngle],这意味着您没有合并访问,也可能是内存库冲突。银行冲突可以解释您观察到的现象。

您应该转置矩阵,然后访问fCorrelationResult[T+iAngle*iNumBins]。你肯定会得到一个很好的加速,并且两个GPU之间可能会有更常规的基准测试。

答案 1 :(得分:0)

使用OpenCL,当内核在特定GPU上运行时,是否可以进入较低级别并找出有关寄存器和共享内存使用情况的内容?

从我对NVIDIA CUDA的有限接触来看,利用率可能是关键所在。 GT240的计算能力为1.2,GTX480为2.0,因此后者具有2倍的寄存器和3倍的共享内存。我的猜测是,OpenCL为第二个内核生成的代码无法在480上使用这些资源。例如,可能存在共享内存库冲突。

相关问题