2014-10-10 32 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

相關問題