0

OpenCLを使用して GPU でツリーをトラバースしたいので、ホストで連続したブロックにツリーをアセンブルし、次のようにデバイスで一貫性を保つためにすべてのポインターのアドレスを変更します。

TreeAddressDevice = (size_t)BaseAddressDevice + ((size_t)TreeAddressHost - (size_t)BaseAddressHost);

メモリ バッファのベース アドレスが必要です。 ホストでは、次のようにバッファにメモリを割り当てます。 cl_mem tree_d = clCreateBuffer(...);

問題は、cl_mems がデータの内部表現を追跡するオブジェクトであることです。技術的にはオブジェクトへのポインターですが、データへのポインターではありません。カーネル内から cl_mem にアクセスする唯一の方法は、setKernelArgs を介して引数として渡すことです。

ここhttp://www.proxy.net/browse.php?u=%3A%2F%2Fwww.khronos.org%2Fmessage_boards%2Fviewtopic.php%3Ff%3D37%26amp%3Bt%3D2900&b=28私は次の解決策を見つけました、しかし、それは動作しません:

__kernel void getPtr( __global void *ptr, __global void *out )

    {
    *out = ptr;
    }

次のように呼び出すことができます

コード:

...

    cl_mem auxBuf = clCreateBuffer( context, CL_MEM_READ_WRITE, sizeof(void*), NULL, NULL );
    void *gpuPtr;

    clSetKernelArg( getterKernel, 0, sizeof(cl_mem), &myBuf );
    clSetKernelArg( getterKernel, 1, sizeof(cl_mem), &auxBuf );
    clEnqueueTask( commandQueue, getterKernel, 0, NULL, NULL );
    clEnqueueReadBuffer( commandQueue, auxBuf, CL_TRUE, 0, sizeof(void*), &gpuPtr, 0, NULL, NULL );

    clReleaseMemObject(auxBuf);

...

これで、"gpuPtr" には、GPU メモリ空間内の "myBuf" の先頭のアドレスが含まれているはずです。

解決策は明白ですが、私はそれを見つけることができませんか? バッファの作成時にデバイス メモリへのポインタを取得するにはどうすればよいですか?

4

2 に答える 2

1

これは、OpenCL モデルでは、ホスト メモリとデバイス メモリがばらばらであるためです。デバイス メモリ内のポインタは、ホスト上では意味がありません。

clEnqueueMapBuffer を使用して、デバイス バッファーをホスト メモリにマップできます。マッピングはデバイスをホストに同期し、マッピング解除はホストをデバイスに同期します。

更新します。コメントで説明しているように、ツリー構造を GPU に送信する必要があります。1 つの解決策は、すべてのツリー ノードを配列内に格納し、ノードへのポインターを配列内のインデックスに置き換えることです。

于 2013-01-15T03:11:26.490 に答える