【问题标题】:OpenCL Kernel Increment returning wrong value, why?OpenCL 内核增量返回错误值,为什么?
【发布时间】:2017-01-15 12:40:27
【问题描述】:

我试图增加全局缓冲区中某个值的值。让我把骨架给你。

__kernel void relax_a_point(__global float* pivot_indices)
{
        int gid = get_global_id(0);
        pivot_indices[gid * 8 + 2] = pivot_indices[gid * 8 + 2] + 1.f;
}

不是将值增加 1,而是将值增加 1024/1023/1022。如果我添加 0.f,则该值保持不变。知道为什么会这样吗?对 pivot_indices 任何元素的任何其他更改(交换等)都会导致输出错误。

pivot_indices 缓冲区是使用 CL_MEM_READ_WRITE 标志创建的。

【问题讨论】:

  • 尝试将 gid 添加到该值而不是 1.f。检查内核是否在具有 [1,1024,1] ndrange 设置的 2D 线程数组上执行
  • 我正在启动 2D 内核,本地大小为 16x16,全局大小为 1024x1024。一旦我切换回本地大小为 1 和全局大小为 1024 的一维内核启动,它就可以正常工作了。

标签: kernel opencl increment


【解决方案1】:

您说您使用的是尺寸为 1024x1024 的 2D 内核,但在:

int gid = get_global_id(0);

工作项 id 仅基于全局维度 0。这意味着,1024 个工作项共享相同的gid。

1024/1023/1022 随机结果是工作项之间的简单数据访问竞争,因为它们之间没有同步。导致一些补充在比赛过程中丢失。

你应该这样做:

__kernel void relax_a_point(__global float* pivot_indices)
{
        int gid = get_global_id(0) + get_global_id(1)*get_global_size(0);
        pivot_indices[gid * 8 + 2] = pivot_indices[gid * 8 + 2] + 1.f;
}

【讨论】:

  • 感谢 DarkZeros。情况就是这样。由于我是 GPU 编程的新手,所以我没有关注工作项的组织。
猜你喜欢
  • 2020-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多