2014-05-14 37 views
1

我已經分離出了一些互不相同的函數,但需要在不同的工作項中並行運行。因此,當內核被調用,它需要決定哪些功能已被執行..我怎樣才能優化我的OpenCl內核

void call_calc0() { 
    // code 
} 

void call_calc1() { 
    // code 
} 

void call_calc2() { 
    // code 
} 

void call_calc3() { 
    // code 
} 

__kernel void perform (__global double* A, __global double* B) { 
    int idx = get_global_id(0); 
    if (idx == 0) { 
     call_calc0(); 
    } else if (idx == 1) { 
     call_calc1(); 
    } else if (idx == 2) { 
     call_calc2(); 
    } else if (idx == 3) { 
     call_calc3(); 
    } 
} 

如果有256/512工作項,此代碼示例將不會是一個正確的做法。我如何優化這個?

+0

我可以想到函數指針和預處理器的方式..但是,有可能在OpenCl中使用函數指針? –

+0

OpenCL中不允許使用函數指針。你是說每一個工作項目都必須執行完全不同的代碼? – jprice

+0

是的。但在相同的緩衝區上。單獨的單個緩衝塊。是否有可能..我做了一些測試@jprice如果我替換if-else單個「if」條件..然後編譯變得非常快...代碼將如果(idx == 1){calc1}; if(idx == 2){calc2} ... –

回答

6

如果可能的話,你最好的優化是使用四個不同的內核。您正在以不止一個的組大小調用此內核,並行執行時會出現問題。

如果完全可能,請嘗試分離您的全局內存或以非常小心,非衝突的方式使用它。這應該允許您創建四個獨立的內核,並擺脫條件代碼執行。

當遇到第一個if/case時,該組中的一些工作項將運行該代碼,但其他75%的工作項將等待。大多數opencl設備,特別是GPU,都以這種方式運行。當這些前25%的工作項目完成時,他們將等待下一個if/case代碼執行。

這適用於opencl中的所有分支,例如if/else,switch,for和while/do。只要你的一些工作項目不滿足條件,他們就會等待滿足它的其他人。然後在「if」組等待時執行「其他」工作組。

另一種看待它的方法是比較CPU和GPU硬件。 CPU有很多專用於分支預測和高速緩衝存儲器的晶體管。 GPU本質上具有更多的向量基礎,並且最近纔開始支持一些更先進的CPU流控功能。

+0

這是GPU中並行化的第一條規則,作爲面向對象編程的第一條規則。將所有內容放在一個單獨的內核/類中,特別是當這些流程完全不相關時,這是一種非常糟糕的方法。有時候,在多個內核/類中分裂工作的懶惰會在將來造成頭痛問題。 – DarkZeros

+1

是的,不知道被調用的函數實際上是如何處理全局內存的,但並不能確定它可以被分解成單獨的內核。 – mfa

2

由於OpenCL不支持函數指針,因此您被限制爲if/elseswitch。這兩者的表現應該是相同的,這只是編碼偏好的差異。

您可以使用預處理器宏使事情變得更簡單/更清晰。例如,你可以做這樣的事情:

#define CALL_CASE(i) \ 
    case i:    \ 
     call_calc##i(); \ 
     break;   \ 

__kernel void perform (__global double* A, __global double* B) { 
    int idx = get_global_id(0); 
    switch (idx) { 
     CALL_CASE(0); 
     CALL_CASE(1); 
     CALL_CASE(2); 
     CALL_CASE(3); 
     ... // etc 
    } 
} 

如果您自動生成你的call_calcX()功能,這將是很容易產生也同時此switch塊。如果您正在手動編寫這些函數,那麼只需要添加一行代碼即可將每個函數添加到塊中。不理想,但也不可怕。

根據上面的註釋,這個問題似乎並不是數據並行的,這會限制利用大多數OpenCL設備中可用的SIMD執行的能力。

+0

我完全同意你的SIMD評論。我需要考慮同樣的情況。正如我的情況數據是MISD一樣。讓我更好地思考更好的算法。但作爲我的問題..你給了我一個解決方案..感謝您的關注.. :) –