在OpenCL中,我的理解是您可以使用该barrier()
函数来同步工作组中的线程.我(通常)了解它们的用途以及何时使用它们.我也知道工作组中的所有线程都必须遇到障碍,否则会出现问题.但是,每次我尝试使用障碍到目前为止,它似乎导致我的视频驱动程序崩溃,或者有关访问某种无效内存的错误消息.到目前为止,我已经在2张不同的显卡上看过这个(1个ATI,1个NVIDIA).
所以,我的问题是:
barrier(CLK_LOCAL_MEM_FENCE)
和之间有什么区别barrier(CLK_GLOBAL_MEM_FENCE)
?我阅读了文档,但对我来说并不清楚.barrier(CLK_LOCAL_MEM_FENCE)
vs. 有一般规则barrier(CLK_GLOBAL_MEM_FENCE)
吗?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)
这样你就不应该有任何内存读取\写入排序问题(只要你确定组中的每个线程都通过障碍,但你知道这一点).
希望能帮助到你.
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页)
归档时间: |
|
查看次数: |
38046 次 |
最近记录: |