2012-07-25 103 views
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); 

我正確的方式嗎?

回答

7

這取決於你如何實際填充你的device陣列。如果您正確初始化它,創建跨越設備的context是正確的。

不幸的是,你對內核和命令隊列有一個錯誤的想法。 A 內核是根據特定上下文的程序創建的。另一方面,隊列用於與某個設備進行通信。你想要做的是每臺設備內核創建一個隊列:

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], /* ... */); 

綜上所述術語:

  • cl_context爲特定cl_platform_id創建並且是等的容器的設備的一個子集,
  • 一個cl_program創建和建造一個cl_context及其相關設備
  • 一個cl_kernelcl_program萃取但只能在與該程序的上下文相關聯的裝置中使用,
  • 一個cl_command_queue是針對特定設備創建屬於某個上下文,內存操作和內核調用被排入命令隊列並在相應的設備上執行。
+1

同意。另外請注意,不同的實現處理跨多個設備分配工作負載不同(有時甚至阻止clEnqueueNDRangeKernel http://stackoverflow.com/questions/11562543/clenqueuendrange-blocking-on-nvidia-hardware-also-multi-gpu/11562814#comment15294577_11562814) - 在某些情況下可能性能較差。要真正在兩臺設備之間分離處理並自行控制它,您可以使用兩個上下文,每個上下文使用一個設備創建。 – Ani 2012-07-25 20:50:14

+0

謝謝。只是一個簡單的問題,我不能使用一個clEnqueueNDRangeKernel語句來啓動這兩個內核嗎? – Nike 2012-07-25 23:43:04

+0

不,不是真的。但是在OpenCL程序中,如果你真的想分離邏輯,你可以調用在同一個程序中定義的其他函數。 – matthias 2012-07-26 06:29:04

相關問題