Opencl 工作项执行命令

Opencl 工作项执行命令,opencl,gpgpu,Opencl,Gpgpu,我在OpenCL工作。我感兴趣的是在下面的示例中如何执行工作项 我的一维范围为10000,工作组大小为512。内核如下所示: __kernel void doStreaming() { unsigned int id = get_global_id(0); if (!isExecutable(id)) return; /* do some work */ } 在这里,它检查是否需要使用以下id继续处理元素 假设执行从512大小的第一个工作组开始,其中20个被isExecu

我在OpenCL工作。我感兴趣的是在下面的示例中如何执行工作项

我的一维范围为10000,工作组大小为512。内核如下所示:

__kernel void
doStreaming() {
  unsigned int id = get_global_id(0);

  if (!isExecutable(id))
    return;

 /* do some work */
}
在这里,它检查是否需要使用以下id继续处理元素

假设执行从512大小的第一个工作组开始,其中20个被
isExecutable
拒绝。GPU是否继续执行其他20个元素而不等待前492个元素


不涉及任何障碍或其他同步技术。

当某些工作项的分支远离通常的/*做一些工作*/时,它们可以通过从下一个波前(amd)或下一个扭曲(nvidia)获取指令来利用管道占用优势,因为当前扭曲/波前工作项正忙于做其他事情。但这可能会导致内存访问序列化和清除工作组的访问顺序,从而降低性能

避免出现发散的扭曲/波前:如果在循环中使用If语句,这真的很糟糕,所以最好找到另一种方法

如果工作组中的每个工作项都有相同的分支,那么就可以了

如果每一个工作项在每数百次计算中只进行很少的分支,那么就可以了

尝试为所有工作项生成相等的条件(非常并行的数据/算法),以利用gpu提供的电源


我所知道的摆脱最简单的分支与计算情况的最佳方法是,使用全局是非数组。0=是,1=否:始终计算,然后将结果与工作项的yes-no元素相乘。通常,每个核添加1字节的元素内存访问比每个核进行一次分支要好得多。实际上,在添加1字节后,将对象长度设为2的幂可能会更好。

是和否。以下详细说明基于NVIDIA的文档,但我怀疑它在ATI硬件上是否有任何不同(尽管实际数字可能不同)。通常,工作组的线程以所谓的扭曲方式执行,即工作组大小的子块。在NVIDIA硬件上,每个工作组分为32个线程。这些扭曲中的每一个都是在锁步中执行的,因此是完全并行的(它可能不是实时并行的,这意味着可能有16个线程并行,然后又有16个线程直接并行,但从概念上讲,它们是完全并行的)。因此,如果这32个线程中只有一个执行额外的代码,其他线程将等待它。但是所有其他经纱中的线都不关心这些

因此,是的,可能会有线程不必要地等待其他线程,但这种情况发生的规模小于整个工作组的规模(在任何NVIDIA硬件上为32个)。这就是为什么在可能的情况下应避免扭曲内分支偏差,这也是为什么保证只在单个扭曲内工作的代码不需要任何同步,例如共享内存访问(一种常见的算法优化)