OpenCL内核中的读写竞争条件会导致数据损坏吗?

时间:2015-03-18 21:02:28

标签: opencl gpu gpgpu nvidia

考虑一对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内存的读写是原子的

我的问题是

  • 在任何当前的GPGPU硬件上都保证这是真的吗?
  • 如果这被OpenCL标准认为是未定义的行为?如果是这样,常见的实现(特别是CUDA工具包中包含的实现)会做什么?
  • 如何测试这个问题?

1 个答案:

答案 0 :(得分:1)

如果您将内核命令排入单个命令队列,该队列是作为按顺序队列创建的(即您在创建时未指定CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE),那么一次只能执行一个内核命令。这意味着您在不同的内核实例之间不会遇到任何此类问题(尽管您在单个内核实例中的工作项之间仍然存在竞争条件,如果它们访问相同的内存位置)。

如果您使用的是无序队列或多个命令队列,那么您可能确实遇到了竞争条件。无法保证您的加载 - 修改 - 存储序列将是原子操作,这将导致未定义的行为。

根据您实际想要对内核执行的操作,您可以使用OpenCL的内置原子函数,它允许您执行一组特定的读 - 修改 - 写操作以原子的方式。