OpenCL的障碍

Jon*_*rlo 44 opencl

在OpenCL中,我的理解是您可以使用该barrier()函数来同步工作组中的线程.我(通常)了解它们的用途以及何时使用它们.我也知道工作组中的所有线程都必须遇到障碍,否则会出现问题.但是,每次我尝试使用障碍到目前为止,它似乎导致我的视​​频驱动程序崩溃,或者有关访问某种无效内存的错误消息.到目前为止,我已经在2张不同的显卡上看过这个(1个ATI,1个NVIDIA).

所以,我的问题是:

  1. 知道为什么会这样吗?
  2. barrier(CLK_LOCAL_MEM_FENCE)和之间有什么区别barrier(CLK_GLOBAL_MEM_FENCE)?我阅读了文档,但对我来说并不清楚.
  3. 关于什么时候使用barrier(CLK_LOCAL_MEM_FENCE)vs. 有一般规则barrier(CLK_GLOBAL_MEM_FENCE)吗?
  4. 有没有时间barrier()用错误的参数类型调用可能会导致错误?

Fel*_*xCQ 33

如您所述,障碍可能只同步同一工作组中的线程.无法在内核中同步不同的工作组.

现在回答你的问题,规范对我来说也不清楚,但在我看来,第6.11.9节包含了答案:

CLK_LOCAL_MEM_FENCE - 屏障函数将刷新存储在本地内存中的任何变量或对内存栅栏进行排队,以确保将内存操作正确排序到本地内存.

CLK_GLOBAL_MEM_FENCE - 屏障函数将对内存栅栏进行排队,以确保将内存操作正确排序到全局内存.当工作项(例如,写入缓冲区或图像存储器对象)然后想要读取更新的数据时,这可能很有用.

因此,据我所知,在写入和读取__local内存空间时应使用CLK_LOCAL_MEM_FENCE,在写入和读取内存空间时应使用CLK_GLOBAL_MEM_FENCE __global.

我没有测试过这是否慢,但大多数时候,当我需要一个屏障并且我对哪个内存空间受到影响有疑问时,我只是使用两者的组合,即:

barrier(CLK_LOCAL_MEM_FENCE | CLK_GLOBAL_MEM_FENCE);
Run Code Online (Sandbox Code Playgroud)

这样你就不应该有任何内存读取\写入排序问题(只要你确定组中的每个线程都通过障碍,但你知道这一点).

希望能帮助到你.

  • 显然CLK_GLOBAL_MEM_FENCE通常比CLK_LOCAL_MEM_FENCE慢.原因是块内的所有线程都必须等待内存访问才能完成.等待全局内存访问完成比本地内存访问要昂贵得多.当然,这并不总是正确的,它取决于访问模式(Fermi现在有缓存,意味着全局访问可以缓存在L1上,它具有与共享内存类似的延迟),内核中的全局/本地内存访问次数,占用率,银行冲突,合并等 (3认同)

mfa*_*mfa 32

在这里恢复旧的线索.我自己遇到了一些障碍().

关于你的碰撞问题,一个潜在的原因可能是你的障碍在一个条件下.我读到当你使用屏障时,组中的所有工作项必须能够达到该指令,否则它将挂起你的内核 - 通常会导致崩溃.

if(someCondition){
  //do stuff
  barrier(CLK_LOCAL_MEM_FENCE);
  //more stuff
}else{
  //other stuff
}
Run Code Online (Sandbox Code Playgroud)

我的理解是,如果一个或多个工作项满足someCondition,那么所有工作项必须满足该条件,否则会有一些工作项跳过障碍.障碍等到所有工作项都达到这一点.要修复上面的代码,我需要重新构建一下:

if(someCondition){
  //do stuff
}
barrier(CLK_LOCAL_MEM_FENCE);
if(someCondition){
  //more stuff
}else{
  //other stuff
}
Run Code Online (Sandbox Code Playgroud)

现在所有工作项目都将达到障碍.

我不知道这在多大程度上适用于循环; 如果一个工作项从for循环中断,它是否会遇到障碍?我不确定.

更新:我已经成功地在for-loop中使用屏障崩溃了几个ocl程序.确保所有工作项同时退出for循环 - 或者更好的是,将屏障放在循环外部.

(来源:使用OpenCL进行异构计算第5章,第90-91页)

  • 感谢您的评论.我也不确定,但我怀疑如果来自该工作组的任何线程,工作组中的所有线程都必须遇到障碍.所以,循环情况,如果工作组中的所有线程在击中障碍之前中断,没问题.但是,如果来自工作组的至少一个线程在循环的特定迭代中遇到障碍,则所有线程(来自该工作组)也必须. (2认同)