通过预取内在函数改进CUDA SDK matrixMul

时间:2012-12-02 22:01:26

标签: cuda gpgpu prefetch

这是CUDA SDK(2.3)matrixMultiply kernel的一部分:

for (int a = aBegin, b = bBegin;
         a <= aEnd;
         a += aStep, b += bStep) {

    __shared__ float As[BLOCK_SIZE][BLOCK_SIZE];
    __shared__ float Bs[BLOCK_SIZE][BLOCK_SIZE];

    int XI=wA * ty + tx;
    int XII=wB * ty + tx;
    ////////////////////
    // PREFETCH BLOCK //
    ////////////////////
    AS(ty, tx) = A[a + XI];
    BS(ty, tx) = B[b + XII];

    __syncthreads();

    for (int k = 0; k < BLOCK_SIZE; ++k)
        Csub += AS(ty, k) * BS(k, tx);

    __syncthreads();
}

此版本的矩阵乘法将磁贴放入共享内存并在共享内存带宽上执行计算。我想通过将下一次迭代的数据预取到L1缓存来提高性能。我按建议here使用预取内在函数,并将以下命令插入上面的PREFETCH BLOCK

    long long int k,kk;
    k=((long long int)A+aStep); if(k<=aEnd) prefetch_l1(k+XI);
    kk=((long long int)B+bStep); if(kk<=aEnd) prefetch_l1(kk+XII);

经过测试,两个版本(有或没有预取)执行非常相似(平均3次运行):

  

没有预取: 6434.866211(ms)

     

预取: 6480.041016(ms)

问题:

我希望看到预取的一些加速,但我对结果感到困惑。任何机构都有理由说明为什么这两个实现非常接近?也许我正在执行错误的预取。

提前谢谢。

更多信息:

GPU:特斯拉C2050

CUDA版本:4.0

inline __device__ void prefetch_l1 (unsigned int addr)
{

  asm(" prefetch.global.L1 [ %1 ];": "=r"(addr) : "r"(addr));
}

1 个答案:

答案 0 :(得分:1)

预取(在任何架构上)只有在以下情况下才有用:

  • 你有足够的内存带宽和
  • 您可以在正确的时间启动预取,即在实际需要数据之前和备用内存带宽可用时提前足够远。

如果你不能满足这些标准,那么预取就无济于事,甚至可能弊大于利。