【问题标题】:What to do if I have more work-items than SIZE_MAX in OpenCL如果我在 OpenCL 中有比 SIZE_MAX 更多的工作项怎么办
【发布时间】:2020-07-30 06:19:54
【问题描述】:

我的 OpenCL 程序涉及大约 70 亿个工作项。在我的 C++ 程序中,我会将其设置为我的 global_item_size:

size_t global_item_size = 7200000000;

如果我的程序编译成 64 位系统(x64),这个全局大小是可以的,因为 SIZE_MAX(size_t 的最大值)远大于 70 亿。但是,为了确保向后兼容性,我想确保我的程序能够编译到 32 位系统 (x86)。在 32 位系统上,SIZE_MAX 约为 40 亿,小于我的全球规模 70 亿。如果我尝试将全局大小设置为 70 亿,则会导致溢出。在这种情况下我该怎么办?

我正在考虑的解决方案之一是制作多维全局大小和局部大小。但是,这种解决方案需要内核计算原始的全局大小(因为我的内核严重依赖全局和局部大小),这会导致性能损失。

我考虑的另一个解决方案是启动多个内核。我认为这个解决方案有点“草率”,同步内核也不是最好的解决方案。

所以我的问题基本上是:我怎样才能(如果可能)使全局大小大于 size_t 的最大大小?如果这不可行,有哪些解决方法?

【问题讨论】:

  • 如果 size_t 是 32 位,CL_DEVICE_MAX_WORK_ITEM_SIZES 也是 32 位,因此不能对更大的内核进行排队。如果可能,get_global_id 也会溢出。你确定32位系统,即4GB内存,甚至可以处理这样的内核吗?因为在这种情况下,甚至没有足够的内存来为每个工作项分配 1 个字节的输入。

标签: opencl


【解决方案1】:

如果你想避免批处理,你可以给每个内核更多的工作,但有效地将代码包装在一个 for 循环中。例如

for (int i = 0; i < WORK_ITEMS_PER_THREAD; ++i)
{
    size_t id = WORK_ITEMS_PER_THREAD * get_global_id(0) + i;

    ...
}

【讨论】:

    【解决方案2】:

    尽量使用uint64_t global_item_size = 7200000000ull;来避免32位整数溢出。

    如果您严格限制工作项的最大 32 位数量,您可以分批进行计算(通过 PCIe 传输在计算步骤之间交换 GPU 缓冲区),或者您可以将多个数据项打包到一个 GPU 线程中.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-01
      • 2018-03-17
      相关资源
      最近更新 更多