在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