【问题标题】:Is the device address of a buffer the same for different kernels/programs in OpenCL对于 OpenCL 中的不同内核/程序,缓冲区的设备地址是否相同
【发布时间】:2014-10-11 00:58:42
【问题描述】:

当将缓冲区作为参数传递给 OpenCL 内核时,内核代码看到的缓冲区地址对于同一个缓冲区是否保持相同?

我用下面的代码检查了一下,地址确实是一样的。但是,我在标准中找不到任何东西来保证这一点。

import pyopencl as cl
import numpy as np

def main():
    ctx = cl.create_some_context()
    queue = cl.CommandQueue(ctx)
    mf = cl.mem_flags
    buf = cl.Buffer(ctx, mf.READ_ONLY, 1000)
    buf2 = cl.Buffer(ctx, mf.READ_WRITE, 8)
    prg = cl.Program(ctx, """
    __kernel void
    get_addr(__global const int *in, __global long *out)
    {
        *out = (long)in;
    }
    """).build()

    knl = prg.get_addr
    knl.set_args(buf, buf2)
    cl.enqueue_task(queue, knl)

    b = np.empty([1], dtype=np.int64)
    cl.enqueue_copy(queue, b, buf2).wait()
    print(b[0])

    prg = cl.Program(ctx, """
    __kernel void
    get_addr(__global const int *in, __global long *out)
    {
        *out = (long)in;
    }
    """).build()
    knl = prg.get_addr
    knl.set_args(buf, buf2)
    cl.enqueue_task(queue, knl)

    b = np.empty([1], dtype=np.int64)
    cl.enqueue_copy(queue, b, buf2).wait()
    print(b[0])

if __name__ == '__main__':
    main()

用例是我正在使用具有许多(数组)参数的 OpenCL 运行模拟。为了不必将这些数组作为参数传递,我将它们填充到一个结构中,并将指针传递给该结构。由于这个结构将被多次使用(并且被所有工作项)我不想在每个内核的每次运行中都填充它,并且想知道指针是否会在不同的运行/工作项之间发生变化。

【问题讨论】:

    标签: opencl pyopencl


    【解决方案1】:

    不保证适用于 OpenCL 1.x。这就是为什么在缓冲区中存储指针是不安全的。运行时允许移动每次内核启动的分配。无法保证它会移动它,当然可以合理地预期缓冲区不需要经常移动,因此您会看到您看到的结果也就不足为奇了。如果您分配更多缓冲区并循环访问它们以强制运行时移动它们,您将更有可能看到问题。

    对于 OpenCL 2.0,共享虚拟内存功能通过定义保证了这一点:如果地址不断变化,则无法共享。

    【讨论】:

    • 是的,我意识到 OpenCL 2.0 中的 SVM 不应该移动,我只是希望 OpenCL 1.x 有类似的保证(可能带有特殊标志)......我想我会在内核的每次运行中填充结构。无论如何,这似乎不是性能瓶颈......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-17
    • 2018-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多