如何for循環中的OpenCL內核執行設備上時,他們的邊界是動態的執行,也就是當每個工作項的for循環執行不同數額的時間?的OpenCL - 動態的循環
AFAIK,內核是指令集(或更好地說一個流)的指令。 GPU設備是一組獨立的計算單元(流式多處理器-SM),每個計算單元包含多個計算單元(流處理器-SP)。
每個SM可以加載一個指令(對於不同的SMS,這可能是不同的指令)從內核(即指令流),並執行所加載的指令爲儘可能多的工作項,因爲在當前SM的SP(每個SP操作相同的指令但具有不同的數據 - SIMD)。
一個SM中的所有SP都必須運行相同的指令,因此在執行for-loop條件後,必須根據每個工作條件的結果做出動態決策,下一條指令是什麼將在SM 和上運行,以便爲其運行的工作項目運行。
基於這個假設,我認爲foobaz
內核(見下文)會更快地執行,因爲當一個工作項完成執行時,另一個工作項可以取代它。
這是假設錯了嗎?
以下哪兩個內核的,foobar
和foobaz
,最終將執行得更快?性能取決於什麼? (一個元素的屬性數量可以比其他元素大一個數量級)。
foobar
;
__kernel void foobar(__global int* elements, /* size N */
__global int* element_properties, /* size N*constant */
__global int* output) /* size N */
{
size_t gid = get_global_id(0);
int reduced = 0;
for (size_t i=N*gid; i<N+N*gid; i++)
reduce += predict_future_events(reduce, element_properties[i]);
output[gid] = reduced;
}
...和foobaz
;
__kernel void foobaz(__global int* elements, /* size N */
__global int* element_properties, /* size upper-bounded */
__global int2* element_properties_ranges, /* size N */
__global int* output) /* size N */
{
size_t gid = get_global_id(0);
int reduced = 0;
// `range.x` = starting index in `element_properties`
// `range.y` = ending index in `element_properties`
int2 range = element_properties_ranges[gid];
for (size_t i=range.x; i<range.y; i++)
reduce += predict_future_events(reduce, element_properties[i]);
output[gid] = reduced;
}
我也許應該指出,這兩個內核都只是僞代碼(所以絕對加速是不是我關心的話)。核心部分卻是,如何將*數據依賴*爲每個線程環路通行證的數量*對*迭代每個線程不變(但高數)影響性能,以及是否我的怎麼做硬件的假設( GPU)處理for-loop是正確的。 – sarasvati
什麼部分是動態的? range.y? –
@huseyintugrulbuyukisik是的。嗯,其實我不知道任何事前既不顆粒'range.x'也不'range.y',所以這兩個值是動態的(我希望我們通過「動態」意味着同樣的事情)。假設'element_properties_ranges'中的值是在執行'foobar'和'foobaz'之前由另一個內核產生的。 – sarasvati