GPU が 2 つ、カーネルが 1 つ、コンテキストが 1 つ、コマンド キューが 2 つ (GPU ごとに 1 つ) あります。各コマンド キューが実行されるループでそれらを実行しようとしましたが、GPU で同時に作業を実行することを期待して、両方queue.finish()
を試しました。queue.flush()
しかし実際には、データが最初に 1 つのデバイスに送信され、GPU がその作業を実行し、次に別の GPU が作業を開始します。単一の GPU の場合の 2 倍の時間がかかります。これは私が達成しようとしているものではありません!
また、バッファーをホスト コードに読み込んでいますが、2 番目の GPU が 1 番目の GPU の結果を待機することが問題になる可能性があると考える人もいるかもしれません。しかし、私はまた、結果の読み取りをコメントアウトしましたが、運がありませんでした。それはまだ同じです。
for (unsigned int iter = 0; iter < numberOfDevices; iter++) {
// Load in kernel source, creating a program object for the context
cl::Program programGA(context, stringifiedSourceCL, true);
// Create the kernel functor
auto kernelGA = cl::make_kernel<cl::Buffer,
cl::Buffer,
cl::Buffer>
(programGA, "kernelGA");
// CREATE THE BUFFERS.
d_pop = cl::Buffer(context, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
(Length * POP_SIZE * sizeof(double)),
pop);
// And other buffers...
// Enqueue the kernel.
kernelGA(cl::EnqueueArgs(queue[iter],
cl::NDRange(POP_SIZE / numberOfDevices)),
d_integerParameters,
d_doubleParameters, ... and so on...);
// Enqueue in the corresponding device.
queue[iter].flush();
// Get results from the queue.
queue[iter].enqueueReadBuffer(buf_half_population,
true,
0,
popSizeMD * sizeof(double),
popMD[iter]);
// Add up the results after every iteration.
for (int in_iter = 0; in_iter < populationSizeMD; in_iter++, it_j++) {
population[it_j] = populationMD[iter][in_iter];
}
}
私の質問は次のとおりです。真の同時実行性を実現し、他の GPU の結果を待たずに GPU を同時に実行するにはどうすればよいですか? 2 つのコンテキストを作成する必要がありますか? 私は何か他のことをすべきですか?
カーネルが 1 つあることに注意してください