我是一個OpenCl的新手。雙重減少opencl教程
我需要在一維雙精度數組上運算一個約化(和運算符)。
我一直在網上游蕩,但我發現的例子很混亂。 任何人都可以發佈一個容易閱讀(也可能是高效的)教程實施?
附加信息: - 我可以訪問一個GPU設備; - 我使用C爲內核代碼
我是一個OpenCl的新手。雙重減少opencl教程
我需要在一維雙精度數組上運算一個約化(和運算符)。
我一直在網上游蕩,但我發現的例子很混亂。 任何人都可以發佈一個容易閱讀(也可能是高效的)教程實施?
附加信息: - 我可以訪問一個GPU設備; - 我使用C爲內核代碼
您提到您的問題涉及60k雙打,這將不適合您的設備的本地內存。我把一個內核放在一起,將你的矢量減少到10-30個左右的值,你可以將它與你的主機程序相加。我在我的機器上遇到雙打問題,但是如果您啓用雙打併將「浮動」更改爲「雙倍」,則此內核應該可以正常工作。我將調試我遇到的雙重問題,併發布更新。
PARAMS:
用法:
潛在的優化:
使inVectorSize(和矢量)爲(工作組大小)*(工作組數)的最高倍數。只用這些數據調用內核。內核均勻地分割數據。在等待回調期間計算主機上任何剩餘數據的總和(或者,爲CPU設備構建相同的內核並僅傳遞剩餘數據)。在上面的步驟#5中添加outVector時,從這個總和開始。這種優化應該保持工作組在整個計算過程中均勻飽和。
__kernel void floatSum(__global float* inVector, __global float* outVector, const int inVectorSize, __local float* resultScratch){
int gid = get_global_id(0);
int wid = get_local_id(0);
int wsize = get_local_size(0);
int grid = get_group_id(0);
int grcount = get_num_groups(0);
int i;
int workAmount = inVectorSize/grcount;
int startOffest = workAmount * grid + wid;
int maxOffest = workAmount * (grid + 1);
if(maxOffset > inVectorSize){
maxOffset = inVectorSize;
}
resultScratch[wid] = 0.0;
for(i=startOffest;i<maxOffest;i+=wsize){
resultScratch[wid] += inVector[i];
}
barrier(CLK_LOCAL_MEM_FENCE);
if(gid == 0){
for(i=1;i<wsize;i++){
resultScratch[0] += resultScratch[i];
}
outVector[grid] = resultScratch[0];
}
}
此外,啓用雙打:
#ifdef cl_khr_fp64
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
#else
#ifdef cl_amd_fp64
#pragma OPENCL EXTENSION cl_amd_fp64 : enable
#endif
#endif
更新:AMD APP KernelAnalyzer得到了一個更新(V12),它的顯示,這個內核的雙精度版本實際上,ALU綁定在5870和6970卡上。
做maxOffset = select(maxOffset,inVectorSize,maxOffset> inVectorSize);而不是分支。 – 2013-03-13 18:51:17
AMD的例子非常簡單。 http://developer.amd.com/documentation/articles/Pages/OpenCL-Optimization-Case-Study-Simple-Reductions.aspx – mfa 2012-04-13 13:32:02
@mfa確實。它適用於小尺寸輸入,但不幸的是我的向量是60000個元素,因此它不適合本地內存。 我實現了它,但發現太遲關於本地內存限制。 – 2012-04-13 16:35:29