OpenCL 本地 int 指针挂起 GPU,在 CPU 上工作正常

Posted

技术标签:

【中文标题】OpenCL 本地 int 指针挂起 GPU,在 CPU 上工作正常【英文标题】:OpenCL local int pointers hangs GPU, works fine on CPU 【发布时间】:2021-12-15 17:29:39 【问题描述】:

我正在尝试与 OpenCL 1.2 和 2.0 相关的不同事情。我找到了一个名为 Generic Address Space 的主题,并用指针尝试了一些东西。谁能告诉我为什么这段代码在我的 CPU 上执行良好(Intel i3 报告 OpenCL 2.1)并在我的 NVIDIA GeForce 940MX 上挂起 2 分钟。

void first(int *ptr) 
  *ptr = 2;


__kernel void sampleKernel(__global const float *a, __global float *d) 
    __private int gid = get_global_id(0);
    __private int group_id = get_group_id(0);
    __local int *ptr1;
    ptr1 = 0;
    first(&ptr1);
    printf("ptr1: %u\n", ptr1);

我不希望在本地 int 指针方面对此代码有任何特定行为,但想了解这里发生了什么。

【问题讨论】:

对我来说看起来像是未定义的行为...不应该是 __local int ptr1; 而不是 __local int *ptr1; @Jardel Lucca 是的。 正如你所说,bevahior 可能是未定义的,所以这就是它在某些设备上工作或不工作的原因。我还有一些其他示例在 CPU 上的常规 GCC 上运行良好,并且在 OpenCL C 上执行相同操作我得到不同的结果。在 OpenCL 中进行指针数学运算或寻址时,有什么重要的事情需要记住吗? 确实必须是__local int ptr1;,否则你将值0设置为指针的地址。 OpenCL 可以像 C99 一样进行指针运算,但是在将变量传递给函数时,地址空间必须匹配。您可以写 void first(__local int *ptr) 或在调用 first 之前将 ptr 转换为 __private int 【参考方案1】:

在 OpemCL 2.0 规范中引入了通用地址空间,但在 OpenCL 1.2 规范中还不允许使用。 Intel 支持 2.0,但 Nvidia 只支持 1.2。如果您将函数参数的地址空间显式设置为本地,它应该也适用于 940MX。否则,函数参数在 OpenCL 1.2 中被隐式视为私有内存空间。

【讨论】:

940MX 规范说它支持 OpenCL 3.0。我在 Ubuntu 中使用 460.91.03 驱动程序,但不确定 SDK/编译器默认选择哪些版本。 @Michal Sobczak OpenCL 3.0 与 1.2 相同,但数量更大,并且 OpenCL 2.X 功能是可选的。 OpenCL 3.0 也支持通用地址空间,但 OpenCL 2.X 支持。

以上是关于OpenCL 本地 int 指针挂起 GPU,在 CPU 上工作正常的主要内容,如果未能解决你的问题,请参考以下文章

gpu上的并行减少和计算错误的opencl

相邻工作项上的 OpenCL 矢量化

带有 OpenCL 的 Intel HD 6000 本地内存带宽 [关闭]

OpenCL 本地内存大小和计算单元数量

在 OpenCl 中,多个 gpu 比单个 gpu 慢。我怎样才能更快?

GPU 中的并行性 - CUDA / OpenCL