我有一个关于 OpenCL 内存一致性模型的问题。请考虑以下内核:
__kernel foo() {
__local lmem[1];
lmem[0] = 1;
lmem[0] += 2;
}
在这种情况下,是否需要任何同步或内存围栏来确保lmem[0] == 3
?
根据 OpenCL 规范的第 3.3.1 节,
在工作项内存中具有加载/存储一致性。
对我来说,这说明分配将始终在增量之前执行。
但是,第 6.12.9 节对mem_fence
函数的定义如下:
对执行内核的工作项的加载和存储进行排序。这意味着mem_fence之前的加载和存储将在mem_fence之后的任何加载和存储之前提交到内存。
这不与第 3.3.1 节相矛盾吗?或者也许我对加载/存储一致性的理解是错误的?我将不胜感激你的帮助。
只要只有一个工作项对local
内存单元执行读/写访问,该工作项就会具有一致的视图。仅当将写入传播到工作组中的其他工作项时,才需要使用屏障提交到内存。例如,OpenCL 实现将被允许在专用寄存器中保留对local
内存的任何更改,直到遇到障碍。在工作项中,一切看起来都很好,但其他工作项永远不会看到这些更改。这就是短语">致力于内存"在 6.12.9 中的解释方式。
本质上,本地内存和障碍之间的交互归结为:
障碍之间:
- 只允许一个工作项对本地存储单元进行读/写访问。
或 - 允许工作组中任意数量的工作项对本地存储单元进行只读访问。
换句话说,任何工作项都不能读取或写入在最后一个屏障之后由另一个工作项写入的本地存储单元。