2014-10-28 70 views
1

我一直在嘗試使用PyOpenCL在GPU上對我的FFT程序進行基準測試。在使用OpenCL的'分析'和python的'time'模塊時,我看到完全不同的結果。要使用分析,我做這樣的事情,PyOpenCL程序的基準標記

queue = cl.CommandQueue(ctx,properties=cl.command_queue_properties.PROFILING_ENABLE) 
<other codes> 
for i in range(N): 
    events.append(prg3.butterfly(queue,(len(twid),),None,twid_dev,<buffers>)) 
    events[i].wait() 
for i in range(N): 
    elapsed = elapsed + 1e-9*(event[i].profile.end - event[i].profile.start) 
print elapsed 

雖然時間模塊可以像這樣使用,

k=time.time() 
for i in range(N): 
    event = prg3.butterfly(queue,(len(twid),),None,twid_dev,<buffers>) 
print time.time()-k 

由於這兩個給出了N = 20完全不同的結果,(而答案遺體相同和正確!),我有以下問題。

  1. 事件分析的確切做法是什麼,它是否增加了在event.wait()中花費的時間?
  2. 由於答案在情況2中沒有event.wait()的情況下是相同的,那麼在恰好執行內核時花費的時間是多少?

請啓發我正確的方法來測試python中的OpenCL程序。

回答

3

你的第二種情況是隻捕獲排隊內核所花費的時間,而不是實際運行它。這些入隊內核調用一旦將內核調用放入隊列中就會返回 - 內核將與主機代碼異步運行。到時內核執行以及,只需添加一個呼叫等待,直到所有排隊的命令已經完成:

k=time.time() 
for i in range(N): 
    event = prg3.butterfly(queue,(len(twid),),None,twid_dev,<buffers>) 
queue.finish() 
print time.time()-k 

你的第一種情況是正確的時序內核執行內部消耗的時間,但不必要地阻止主機之間每個內核調用。你可以只用再一次queue.finish()所有的命令已被排隊:

for i in range(N): 
    events.append(prg3.butterfly(queue,(len(twid),),None,twid_dev,<buffers>)) 
queue.finish() 
for i in range(N): 
    elapsed = elapsed + 1e-9*(event[i].profile.end - event[i].profile.start) 
print elapsed 

這兩種方法應該返回幾乎相同的時間。

+1

謝謝,這是有道理的。但沒有event.wait()或queue.finish(),我將無法獲得正確的答案。所以,內核必須在那段時間內執行,並且輸出已準備好被複制到主機。任何意見? – 2014-10-28 17:04:44

+2

@KarthikHegde是 - 當您將數據複製回主機(例如,使用阻止讀取操作)時,將強制所有先前提交的命令完成。 – jprice 2014-10-28 18:35:34