相关疑难解决方法(0)

分支差异真的那么糟糕吗?

我看到很多问题散布在互联网上,关于分支差异,以及如何避免分歧.然而,即使在阅读了几篇关于CUDA如何工作的文章之后,我似乎也无法看到在大多数情况下如何避免分支差异.在有人用伸出的爪子抓住我之前,请允许我描述我认为是"大多数情况".

在我看来,大多数分支差异实例涉及许多真正不同的代码块.例如,我们有以下场景:

if (A):
  foo(A)
else:
  bar(B)
Run Code Online (Sandbox Code Playgroud)

如果我们有两个线程遇到这种分歧,线程1将首先执行,采用路径A.接下来,线程2将采用路径B.为了消除分歧,我们可能会将上面的块更改为如下所示:

foo(A)
bar(B)
Run Code Online (Sandbox Code Playgroud)

假设foo(A)在线程2和bar(B)线程1上调用是安全的,可能会期望性能得到改善.但是,这是我看到它的方式:

在第一种情况下,线程1和2串行执行.调用这两个时钟周期.

在第二种情况下,线程1和2 foo(A)并行执行,然后bar(B)并行执行.这仍然看起来像两个时钟周期,区别在于在前一种情况下,如果foo(A)涉及从内存中读取,我想线程2可以在该延迟期间开始执行,这导致延迟隐藏.如果是这种情况,分支发散代码更快.

performance branch cuda

33
推荐指数
1
解决办法
2万
查看次数

在GPU编程中使用条件时,工作项执行什么?

如果您在波前执行工作项并且存在条件,例如:

  if(x){
        ...
  }
  else{
       ....
  }
Run Code Online (Sandbox Code Playgroud)

工作项执行什么?是这样的情况,波前的所有工作项都将执行第一个分支(即x == true).如果没有x为false的工作项,则跳过其余的条件?

如果一个工作项采用替代路径会发生什么.我是否告诉所有工作项也将执行备用路径(因此执行两个路径?).为什么会出现这种情况,以及如何解决程序执行问题

cuda gpu gpgpu opencl gpu-programming

7
推荐指数
1
解决办法
5075
查看次数

指令级并行和线程级并行如何在GPU上运行?

假设我正在尝试对数组大小n进行简单的缩减,比如保持在一个工作单元内...说添加所有元素.一般策略似乎是在每个GPU上生成许多工作项,这会减少树中的项目.天真地看起来似乎采取了log n步骤,但它并不像第一波线程所有这些线程一次性进行,是吗?它们被安排在经线中.

for(int offset = get_local_size(0) / 2;
      offset > 0;
      offset >>= 1) {
     if (local_index < offset) {
       float other = scratch[local_index + offset];
       float mine = scratch[local_index];
       scratch[local_index] = (mine < other) ? mine : other;
     }
     barrier(CLK_LOCAL_MEM_FENCE);
   }
Run Code Online (Sandbox Code Playgroud)

因此,并行添加了32个项目,然后该线程在屏障处等待.另外32人去,我们在障碍物等待.另外32个,我们在屏障处等待,直到所有线程都完成了必要的n/2次添加以进入树的最顶层,然后我们绕过循环.凉.

这看起来不错,但也许很复杂?我理解指令级并行是一个大问题,所以为什么不产生一个线程并做类似的事情

while(i<array size){
    scratch[0] += scratch[i+16]
    scratch[1] += scratch[i+17]
    scratch[2] += scratch[i+17]
    ...
    i+=16
}
...
int accum = 0;
accum += scratch[0]
accum += scratch[1]
accum += scratch[2]
accum += scratch[3]
...
Run Code Online (Sandbox Code Playgroud)

这样所有的添加都发生在经线内.现在你有一个线程可以保持gpu的忙碌程度.

现在假设指令级并行性不是真的.如下所示,工作大小设置为32(warp数).

for(int i …
Run Code Online (Sandbox Code Playgroud)

cuda nvidia opencl

3
推荐指数
1
解决办法
2040
查看次数

如何理解"warp中的所有线程同时执行相同的指令." 在GPU?

我正在阅读专业CUDA C编程,并在GPU架构概述部分:

CUDA采用单指令多线程(SIMT)架构来管理和执行32个被称为warp的组中的线程.warp中的所有线程同时执行相同的指令.每个线程都有自己的指令地址计数器和寄存器状态,并对自己的数据执行当前指令.每个SM将分配给它的线程块分区为32线程warp,然后调度它以便在可用的硬件资源上执行.

SIMT架构类似于SIMD(单指令,多数据)架构.SIMD和SIMT都通过向多个执行单元广播相同的指令来实现并行性.一个关键的区别是SIMD要求向量中的所有向量元素在一个统一的同步组中一起执行,而SIMT允许同一warp中的多个线程独立执行.即使warp中的所有线程在同一程序地址处一起启动,单个线程也可能具有不同的行为.SIMT使您能够为独立的标量线程编写线程级并行代码,以及为协调线程编写数据并行代码.SIMT模型包括SIMD不具备的三个关键功能:
➤每个线程都有自己的指令地址计数器.
➤每个线程都有自己的寄存器状态.
➤每个线程都可以有一个独立的执行路径.

第一段提到" All threads in a warp execute the same instruction at the same time.",而在第二段则提到" Even though all threads in a warp start together at the same program address, it is possible for individual threads to have different behavior.".这让我感到困惑,上述陈述似乎是矛盾的.任何人都可以解释一下吗?

cuda gpu nvidia gpu-programming multiple-gpu

2
推荐指数
1
解决办法
1070
查看次数