2014-10-10 34 views
0

将缓冲区作为参数传递给OpenCL内核时,内核代码所看到的缓冲区的地址是否对同一缓冲区保持不变?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的模拟器,它有很多(数组)参数。为了不必将这些数组作为参数传递,我将它们填充到一个结构体中,并将​​指针传递给结构体。由于这个结构将被多次使用(并被所有工作项目使用),我不想在每个内核的每次运行中都填充它,并且想知道指针是否会在不同的运行/工作项目之间发生变化。

回答

1

OpenCL 1.x不能保证。这就是为什么将指针存储在缓冲区中是不安全的。允许运行时为每个内核启动移动分配。这并不能保证它会移动它,当然有理由期望缓冲区通常不需要移动,所以你看到你看到的结果并不奇怪。如果你分配了更多的缓冲区并循环遍历它们来迫使运行时间移动它们,你将更有可能看到问题。

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

+0

是的,我意识到在OpenCL 2.0中的SVM不应该移动,我只是希望OpenCL 1.x有类似的保证(也许有特殊的标志)....我想我会只填充每个结构内核运行。它似乎并不是性能瓶颈...... – yuyichao 2014-10-10 18:13:03

相关问题