5

OpenCLでプログラミングを開始したとき、カーネルにデータを提供するために次のアプローチを使用しました。

cl_mem buff = clCreateBuffer(cl_ctx, CL_MEM_READ_WRITE, object_size, NULL, NULL);
clEnqueueWriteBuffer(cl_queue, buff, CL_TRUE, 0, object_size, (void *) object, NULL, NULL, NULL);

これには明らかに、データをチャンクに分割して、各チャンクがデバイスのメモリに収まるようにする必要がありました。計算を実行した後、clEnqueueReadBuffer()を使用してデータを読み取ります。しかし、ある時点で、次の行を使用できることに気付きました。

cl_mem buff = clCreateBuffer(cl_ctx, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, object_size, (void*) object, NULL);

これを行うと、データのパーティション化は廃止されました。そして驚いたことに、パフォーマンスが大幅に向上しました。それは私にはわかりません。私が得たものから、ホストポインタを使用する場合、デバイスメモリはキャッシュとして機能しますが、処理のためにすべてのデータをそこにコピーし、終了したらメインメモリにコピーして戻す必要があります。明示的なコピー(clEnqueRead / WriteBuffer)を使用すると、基本的に同じであるはずなのに、どうして桁違いに遅くなるのでしょうか。私は何かが足りないのですか?

ありがとう。

4

2 に答える 2

3

はい、clEnqueueWriteBuffer 呼び出しに CL_TRUE がありません。これにより、書き込み操作がブロックされ、コピーの作成中に CPU が停止します。ホスト ポインターを使用すると、OpenCL 実装はコピーを非同期にすることでコピーを「最適化」できるため、全体としてパフォーマンスが向上します。

これは CL の実装に依存することに注意してください。高速/同等/低速になる保証はありません。

于 2010-08-09T19:50:04.003 に答える