我有两个 GPU、一个内核、一个上下文和两个命令队列(每个 GPU 1 个)。我试图在每个命令队列都运行的循环中运行它们,然后我尝试了两者queue.finish()
,并queue.flush()
希望同时在 GPU 上运行工作。
但实际发生的情况是,数据首先发送到一个设备,GPU 执行其工作,然后另一个 GPU 开始工作。它花费的时间是单个 GPU 的两倍。这不是我打算实现的!
虽然我也在将缓冲区读回主机代码,但有人可能认为这可能是第二个 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 同时运行而不等待另一个结果?我应该创建两个上下文吗?我应该做点别的吗?
请记住,只有一个内核