【问题标题】:Declare __global object inside kernel在内核中声明 __global 对象
【发布时间】:2015-07-01 20:22:18
【问题描述】:

我试图在内核中声明一个 __global 内存块,比如

__global float arr[200];

我假设这会在全局内存中创建一个我可以在内核中引用的数组。程序编译成功,但随后 当我运行它时,它显示:

错误:具有自动存储持续时间的变量 不能存储在命名地址空间中

我不知道为什么会这样。 为了使用全局内存,我们是不是必须在使用前在主机端创建一个缓冲区?

如果我想创建一个由所有线程共享的数组,除了为这个全局数组传递另一个新参数之外,我能做些什么呢?

【问题讨论】:

    标签: memory opencl


    【解决方案1】:

    您可以在程序范围内分配它,至少在 OpenCL 2 中。

    __global float arr[200];
    kernel void foo()
    {
       if(get_global_id(0) == 0)
         arr[0] = 3;
    }
    

    当然,虽然初始化要小心,但没有办法在分派中同步工作项,因此如果您有多个工作组,初始化它并在同一个内核中使用它是不切实际的。

    在内核范围内分配它并没有多大意义。如果工作组被序列化,内核代码中分配的全局数组的生命周期是多少?它是否应该比工作组、调度、永久保留以在该内核和下一个内核之间共享?显而易见的可能是它与内核具有相同的生命周期,但是没有竞争就不可能初始化和使用。如果它在多个内核中是持久的,那么主机分配或程序范围分配更有意义。

    为什么传递一个新参数是个问题?

    【讨论】:

    • 其实没问题。只是想知道是否有任何方法可以避免主机设备传输。
    • 啊,如果你只运行一次它总是会进行传输,除非你在设备上计算。如果您通过运行时分配并且不向其中写入任何数据,则可以避免主机->设备传输。无论发生什么,它都必须将二进制文件复制到设备上,并且该二进制文件将包含数据。驱动程序更有可能以与运行时分配的方式大致相同的方式分配程序范围全局变量。
    【解决方案2】:

    __global 内存对象只能通过主机端的 API 调用来分配。 您还可以使用__local 内存对象,该对象可以通过主机端和内核内部的 API 调用分配,并且对工作组内的所有线程可见。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 2019-07-26
      • 2013-01-30
      • 2021-12-04
      • 2016-03-04
      • 1970-01-01
      相关资源
      最近更新 更多