在Nvidia GPU上,当我拨打clEnqueueNDRange
时,程序会在继续之前等待它完成。更确切地说,我打电话给它的等效C++绑定,CommandQueue::enqueueNDRange
,但这不应该有所作为。这只发生在Nvidia硬件(3 Tesla M2090s)上;在我们配备AMD GPU的办公室工作站上,呼叫不受阻碍,并立即返回。我没有本地的Nvidia硬件来测试 - 我们曾经这样做过,而且我也记得类似的行为,但它有点朦胧。clEnqueueNDRange在Nvidia硬件上阻塞? (也是多GPU)
这使得难以在多个GPU之间传播工作。我已经尝试在新的C++ 11规范中使用std::async
/std::finish
来启动一个新线程,以便每次调用enqueueNDRange,但这似乎并不奏效 - 监控nvidia-smi中的GPU使用情况,我可以看到GPU 0上的内存使用量上升,然后它做了一些工作,然后GPU 0上的内存下降,GPU 1上的内存上升,一个做一些工作等等。我的gcc版本是4.7.0。
这里是我是如何开始的内核,其中增量所需的全球工作的尺寸由设备的数量划分,四舍五入到所需的地方工作的大小最接近的倍数:
std::vector<cl::CommandQueue> queues;
/* Population of queues happens somewhere
cl::NDrange offset, increment, local;
std::vector<std::future<cl_int>> enqueueReturns;
int numDevices = queues.size();
/* Calculation of increment (local is gotten from the function parameters)*/
//Distribute the job among each of the devices in the context
for(int i = 0; i < numDevices; i++)
{
//Update the offset for the current device
offset = cl::NDRange(i*increment[0], i*increment[1], i*increment[2]);
//Start a new thread for each call to enqueueNDRangeKernel
enqueueReturns.push_back(std::async(
std::launch::async,
&cl::CommandQueue::enqueueNDRangeKernel,
&queues[i],
kernels[kernel],
offset,
increment,
local,
(const std::vector<cl::Event>*)NULL,
(cl::Event*)NULL));
//Without those last two casts, the program won't even compile
}
//Wait for all threads to join before returning
for(int i = 0; i < numDevices; i++)
{
execError = enqueueReturns[i].get();
if(execError != CL_SUCCESS)
std::cerr << "Informative error omitted due to length" << std::endl
}
的内核肯定应该在对std::async
的调用中运行,因为我可以创建一个虚拟函数,在GDB上设置一个断点并在调用std::async
时进入它。但是,如果我为enqueueNDRangeKernel创建一个包装函数,请在此处运行它,然后在运行后放入一个打印语句,我可以看到在打印之间需要一些时间。
P.S.由于黑客等原因,Nvidia开发区已经关闭,所以我无法在那里发布问题。
编辑:忘了提 - 那我传递给内核作为argment(和一个我提到,上面,这似乎让GPU之间传递)被声明为使用CL_MEM_COPY_HOST_PTR的缓冲区。我一直在使用CL_READ_WRITE_BUFFER,效果相同。
那么,这是否意味着clEnqueueNDRange只能在任何给定的上下文中一次调用一次?这似乎是这种情况,正如我对'std :: async'的实验所暗示的那样。 编辑:或者,而不是一次调用一次,一次执行一个。 – Chaosed0 2012-07-19 14:19:07
从我的实验来看,是的。每当我想要做更复杂的事时,我都会使用AMD(或Intel)实现。但是,您可以创建两个上下文,每个上下文都有一个设备,对吗? – Ani 2012-07-19 14:20:50
井dangit。我的设置的问题是我需要此代码在多GPU设置上运行,并且我已经访问的两个GPU群集都有Nvidia卡。如果没有解决方法,那么我有点死在水里。在论坛不通的情况下向Nvidia的支持发送电子邮件是否值得? arghedit:是的,我想我可以尝试单独的上下文。 – Chaosed0 2012-07-19 14:22:10