CUDA循环在三角形区域展开

时间:2015-04-28 01:51:10

标签: cuda loop-unrolling

是否可以在三角形区域上展开循环,例如:

for (int i = 0; i < ROW_LENGTH; i++)
{
    for (int j = 0; j < i; j++)
    {
        // Some array operation here
    }
}

其中ROW_LENGTH是在编译时定义的常量?现在看来,我不认为这是可能的,因为我在程序执行时正在改变(更重要的是,它在编译时不是常量)。我想你可以将2D数组视为一维数组,从0迭代到(ROW_LENGTH ^ 2)/ 2,然后尝试几个数学技巧来获取索引,但是额外的操作会破坏循环展开的目的。第一名。

1 个答案:

答案 0 :(得分:2)

CUDA 7.0编译器将在我的测试中展开它。循环索引在编译时都是已知的,所以没有理由不能这样做。

考虑以下代码,将a的三角形部分设置为1。

#define ROW_LENGTH 4
__global__ void triUnrollTest1(float* a) {
   #pragma unroll
   for (int i = 0; i < ROW_LENGTH; i++)
   {
      #pragma unroll
      for (int j = 0; j < i; j++)
      {
         a[i * ROW_LENGTH + j] = 1.f;
      }
   }
}

仅{4}我们可以自己展开:

ROW_LENGTH

使用CUDA 7.0编译SM 35: __global__ void triUnrollTest2(float* a) { a[1 * ROW_LENGTH + 0] = 1.f; a[2 * ROW_LENGTH + 0] = 1.f; a[2 * ROW_LENGTH + 1] = 1.f; a[3 * ROW_LENGTH + 0] = 1.f; a[3 * ROW_LENGTH + 1] = 1.f; a[3 * ROW_LENGTH + 2] = 1.f; }

然后转储SASS汇编程序: nvcc -arch=sm_35 -c triUnroll.cu

我们得到:

cuobjdump --dump-sass triUnroll.o

显然两者都是相同的并且很好地展开。有趣的是,当我第一次使用6.5编译时,编译器没有展开,所以我想在这种情况下更新是值得的!