具有单个分支的CUDA内核运行速度比没有分支

时间:2017-09-20 22:22:11

标签: performance cuda gpu-warp

我在有和没有分支的过滤器内核上有一个奇怪的性能反转。具有分支的内核运行速度比没有分支的内核快1.5倍。

基本上我需要对一束辐射光线进行排序然后应用交互内核。由于有很多附带的数据,我不能多次使用thrust :: sort_by_key()这样的东西。

算法的想法:

  1. 为所有可能的交互类型(五个)运行循环
  2. 在每个周期,经线投票选择其交互类型
  3. 循环完成后,每个warp线程都知道具有相同交互类型的另一个线程
  4. 线程选择他们的领导者(每种交互类型)
  5. 领导者使用atomicAdd更新交互偏移表
  6. 每个线程将其数据写入相应的偏移量
  7. 我使用了这篇Nvidia帖子https://devblogs.nvidia.com/parallelforall/cuda-pro-tip-optimized-filtering-warp-aggregated-atomics/

    中描述的技巧

    我的第一个内核包含一个内部循环分支,运行时间约为5毫秒:

    int active;
    int leader;
    int warp_progress;
    for (int i = 0; i != hit_interaction_count; ++i)
    {
      if (i == decision)
      {
        active = __ballot(1);
        leader = __ffs(active) - 1;
        warp_progress = __popc(active);
      }
    }
    

    我的第二个内核使用两个元素的查找表,不使用分支并运行~8ms:

    int active = 0;
    for (int i = 0; i != hit_interaction_count; ++i)
    {
      const int masks[2] = { 0, ~0 };
      int mask = masks[i == decision];
      active |= (mask & __ballot(mask));
    }
    int leader = __ffs(active) - 1;
    int warp_progress = __popc(active);
    

    共同部分:

    int warp_offset;
    if (lane_id() == leader)
      warp_offset = atomicAdd(&interactions_offsets[decision], warp_progress);
    warp_offset = warp_broadcast(warp_offset, leader);
    ...copy data here...
    

    怎么会这样?有没有办法实现这样的过滤器内核,所以它运行得比分支一个?

    UPD:完整的源代码可以在https://bitbucket.org/radiosity/engine/src

    filter_kernel cuda_equation / radiance_cuda.cu中找到

1 个答案:

答案 0 :(得分:1)

我认为这是CPU程序员的大脑变形。在CPU上我期望性能提升,因为消除了分支和分支错误预测惩罚。

但GPU上没有分支预测且没有惩罚,所以只有指令才算重要。

首先,我需要将代码重写为简单的代码。

有分支:

int active;
for (int i = 0; i != hit_interaction_count; ++i)
    if (i == decision)
        active = __ballot(1);

没有分支:

int active = 0;
for (int i = 0; i != hit_interaction_count; ++i)
{
  int mask = 0 - (i == decision);
  active |= (mask & __ballot(mask));
}

在第一个版本中,有大约3个操作:compareif__ballot()。 在第二个版本中,有大约5个操作:comparemake mask__ballot()&|=。 共同代码中有大约15个操作。

两个循环运行5个循环。它首先是35个操作,第二个是45个操作。此计算可以解释性能下降。