考虑一对OpenCL内核,它们读写相同的内存位置。举个简单的例子,考虑以下OpenCL程序:
__kernel void k1(__global int * a)
{
a[0] = 2*a[1];
}
__kernel void k2(__global int * a)
{
a[1] = a[0]-1;
}
如果启动了许多线程,运行这些内核中的许多线程,则全局内存的结果状态是不确定的。
这仍然可能允许编写异步算法,该算法接受内核中任何可能的操作顺序。
但是,这要求对全局GPU内存的读写是原子的。
我的问题是
答案 0 :(得分:1)
如果您将内核命令排入单个命令队列,该队列是作为按顺序队列创建的(即您在创建时未指定CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE
),那么一次只能执行一个内核命令。这意味着您在不同的内核实例之间不会遇到任何此类问题(尽管您在单个内核实例中的工作项之间仍然存在竞争条件,如果它们访问相同的内存位置)。
如果您使用的是无序队列或多个命令队列,那么您可能确实遇到了竞争条件。无法保证您的加载 - 修改 - 存储序列将是原子操作,这将导致未定义的行为。
根据您实际想要对内核执行的操作,您可以使用OpenCL的内置原子函数,它允许您执行一组特定的读 - 修改 - 写操作以原子的方式。