2012-01-27 86 views
4

有沒有辦法阻止OpenCL內核執行? 例如,我進入內核,做一些計算,然後停止它,如果某些條件得到滿足,否則,我等待它完成:有沒有辦法阻止OpenCL內核執行?

clEnqueueNDRange(queue, ...); // start kernel function 

// do other stuff... 
// ... 

if (some condition met) { 
    stopKernel(); 
} else { 
    clFinish(queue); 
} 

謝謝大家幫忙

回答

7

號一旦你已經入隊了你的內核,它會運行完成。

之一來完成東西像上面的方法是做到這一點:

while (data_left_to_process) { 

    clEnqueueNDRangeKernel(..., NDRange for a portion of the data, ...) 

    // other work 

    if (condition) { 
     break; 
    } 

    // adjust NDRange for next execution to processes the next part of your data 

} 

clFinish(queue); 

這可以讓你避免處理所有的數據,具有明顯的權衡,你現在在更小的塊提交工作,這可能會對性能產生影響。

2

可能。

  1. 在上下文中創建兩個命令隊列。
  2. 創建兩個內核,一個執行工作,另一個執行中止。每個內核都可以訪問共享的全局緩衝區。
  3. 將第一個內核加載到隊列1中。
  4. 當您想暫停執行時,將第二個內核加載到隊列2中。

或者,您可以使用無序隊列並將第二個內核加載到同一個命令隊列中以暫停執行。你必須小心一些(必要時使用clFinish/clFlush),但這是更自然的做法。

(多隊列)的一些僞代碼:

clEnqueueNDRange(queue1, kernel1, ...); //start work kernel 
// do other stuff 
// ... 
if (condition) 
    clEnqueueNDRange(queue2, kernel2, ...); //stop work kernel 
clFinish(queue1); 
clFinish(queue2); // entirely unnecessary if using in-order queues 

使用INT緩衝區或浮動作爲您停止變量,並通過您的內核中的global_id訪問它們,以減少內的全球閱讀成本循環。缺點是你的狀態是不確定的:沒有進一步的變量來計算執行等,你不知道有多少工作項目和哪些已經被執行。

而且內核:

void kernel1(... ,global int * g_stop) 
{ 
    int index_from_ids = ...; 
    while (g_stop[index_from_ids] == 0) // or 'if' for single pass execution 
    { 
     // do work here 
    } 
} 

void kernel2(... ,global int * g_stop) 
{ 
    int index_from_ids = ...; 
    g_stop[index_from_ids] = 1; 
} 
+0

有沒有一種方法,使該解決方案100%定義的行爲,比如用原子INT? – galinette 2018-02-16 10:10:20

相關問題