私はOpenCLを調べていますが、このカーネルが実行されると予想される方法と比較して、なぜこのカーネルの実行が非常に遅いのか少し混乱しています。カーネルは次のとおりです。
__kernel void copy(
const __global char* pSrc,
__global __write_only char* pDst,
int length)
{
const int tid = get_global_id(0);
if(tid < length) {
pDst[tid] = pSrc[tid];
}
}
次の方法でバッファを作成しました。
char* out = new char[2048*2048];
cl::Buffer(
context,
CL_MEM_USE_HOST_PTR | CL_MEM_WRITE_ONLY,
length,
out);
入力バッファについても同様ですが、inポインタをランダムな値に初期化した点が異なります。最後に、カーネルを次のように実行します。
cl::Event event;
queue.enqueueNDRangeKernel(
kernel,
cl::NullRange,
cl::NDRange(length),
cl::NDRange(1),
NULL,
&event);
event.wait();
次のように計算すると、平均時間は約75ミリ秒です。
cl_ulong startTime = event.getProfilingInfo<CL_PROFILING_COMMAND_START>();
cl_ulong endTime = event.getProfilingInfo<CL_PROFILING_COMMAND_END>();
std::cout << (endTime - startTime) * SECONDS_PER_NANO / SECONDS_PER_MILLI << "\n";
Intel i5-3450チップ(Sandy Bridgeアーキテクチャ)を搭載したWindows7を実行しています。比較のために、コピーを行う「直接」の方法は5ミリ秒未満かかります。event.getProfilingInfoには、ホストとデバイス間の通信時間が含まれているとは思いません。考え?
編集:
ananthonlineの提案で、charsの代わりにfloat4sを使用するようにカーネルを変更しました。これにより、平均実行時間が約50ミリに短縮されました。それでも私が望んでいたほど速くはありませんが、改善されています。ananthonlineに感謝します!