我是OpenCL的新手,我正在嘗試計算灰度圖像的直方圖。我正在GPU nvidia GT 330M上執行此計算。本地內存Opencl大小對速度有影響嗎?
代碼
__kernel void histogram(__global struct gray * input, __global int * global_hist, __local volatile int * histogram){
int local_offset = get_local_id(0) * 256;
int histogram_global_offset = get_global_id(0) * 256;
int offset = get_global_id(0) * 1920;
int value;
for(unsigned int i = 0; i < 256; i++){
histogram[local_offset + i] = 0;
}
barrier(CLK_LOCAL_MEM_FENCE);
for(unsigned int i = 0; i < 1920; i++){
value = input[offset + i].i;
histogram[local_offset + value]++;
}
barrier(CLK_LOCAL_MEM_FENCE);
for(unsigned int i = 0; i < 256; i++){
global_hist[histogram_global_offset + i] = histogram[local_offset + i];
}
}
此計算圖像1920 * 1080進行。
當直方圖的局部尺寸設置爲256 *的sizeof(cl_int)這種計算速度(通過NVIDIA nsight性能分析)11 675微秒,我燒的內核與
queue.enqueueNDRangeKernel(kernel_histogram, cl::NullRange, cl::NDRange(1080), cl::NDRange(1));
。
由於本地工作組大小設置爲1。我嘗試將本地工作組大小增加到8.但是,當我將直方圖的局部大小增加到256 * 8 * sizeof(cl_int)並使用本地wg大小1進行計算時,我得到85 177微秒。
所以,當我用每個工作組的8個內核啓動它時,我不會從11ms,而是從85ms加速。因此,每個Worgroup擁有8個內核的最終速度爲13 714微秒。
但是,當我創建計算錯誤,將local_offset設置爲零,並且本地直方圖的大小爲256 * sizeof(cl_int)並且每個工作組使用8個內核時,我獲得了更好的時間 - 3 854微秒。
有沒有人有一些想法來加速這種計算?
謝謝!
您發佈的示例代碼似乎正在處理每個工作項圖像的一行。當你爲每個工作組啓動多個工作項目時,你還在這麼做,還是讓每個工作組合作處理一行?當你這樣做時,你能向我們展示你使用的內核和主機代碼嗎? – jprice
感謝您的回覆。是的,我正在使用這種方法,一個線程計算一行。 –
這會導致較差的內存訪問性能。理想情況下,您希望您的內存訪問得以合併 - 也就是說,相鄰的工作項目應儘可能訪問相鄰的內存地址。 – jprice