2

基本上我有两个 GPU,我想在每个 GPU 上执行一些内核。我不希望 GPU 在同一个内核上工作,每个内核都做其中的一部分(我不知道这是否可能),以防万一我什至不想看到这种行为。

我只是想确保这两种设备都在使用。我已经为它们创建了上下文和命令队列。但是我看到只执行了一个内核,这意味着只使用了一个设备。我就是这样做的。. .

cl_device_id *device;
cl_kernel *kernels;
...
// creating context.  
context = clCreateContext(0, num_devices, device, NULL, NULL, &error);
...
// creating command queues for all kernels
for(int i = 0; i<num_kenrels; i++)
    cmdQ[i] = clCreateCommandQueue(context, *device, 0, &error);
...
// enqueue kernels 
error = clEnqueueNDRangeKernel(*cmdQ, *kernels, 2, 0, glbsize, 0, 0, NULL, NULL);

我走的是正确的路吗?

4

1 回答 1

7

这取决于您实际填充device数组的方式。如果您正确初始化它,则创建context跨设备是正确的。

不幸的是,您对内核和命令队列有一个错误的想法。内核是从针对特定上下文的程序创建的。另一方面,队列用于与某个设备进行通信您要做的是为每个设备而不是内核创建一个队列:

for (int i = 0; i < num_devices; i++)
    cmdQ[i] = clCreateCommandQueue(context, device[i], 0, &error);

现在您可以通过相应的命令队列将不同(或相同)的内核排入不同设备上:

clEnqueueNDRangeKernel(cmdQ[0], kernels[0], /* ... */);
clEnqueueNDRangeKernel(cmdQ[1], kernels[1], /* ... */);

总结一下条款:

  • Acl_context是为特定设备创建的cl_platform_id,就像是设备子集的容器,
  • a是为 a及其关联设备cl_program创建和构建的cl_context
  • acl_kernel是从 a 中提取的,cl_program但只能在与程序上下文关联的设备上使用,
  • acl_command_queue是为属于特定上下文的特定设备创建的,
  • 内存操作和内核调用在命令队列中排队并在相应的设备上执行。
于 2012-07-25T20:39:05.763 回答