我在OpenCL中完成了Window Function内核。基本上,窗口函数只是将一组系数应用于另一组数字(维基百科更好地解释它)。在大多数情况下,我能够将窗口系数浮点数组填充到常量缓存中。关于我的OpenCL内核(DSP窗口函数)分析结果的困惑
我预计Compute Prof的结果表明,主机到设备和设备到主机的内存传输将花费超过95%的处理时间。几乎所有的情况下,只有80%的处理时间。我正在写和读一个420万浮点阵列,并写出另一个浮点数组,通常保持在一百万以下。
在内核中是否有任何东西看起来很腥?任何意见,如果它是一个问题,应该在GPU上运行得比CPU更快(我仍然不是100%)。我有点震惊,为什么我的gld_efficiency和gst_efficiency在0.1和0.2之间徘徊。我在考虑G80全局内存的情况下制作了这个内核。我的全局内存整体吞吐量似乎是40gbs。内核非常简单,并在下面发布。
__kernel void window(__global float* inputArray, // first frame to ingest starts at 0. Sized to nFramesToIngest*framesize samples
__constant float* windowArray, // may already be partly filled
int windowSize, // size of window frame, in floats
int primitivesPerDataFrame, //amount of primitives in each frame of inputArray parameter
int nInFramesThisCall, //each thread solves a frame, so this integer represent how many threads this kernel launches
int isRealNumbers //0 for complex, non-zero for real
)
{
int gid = get_global_id(0) + get_global_size(0) * get_global_id(1);
if(gid < nInFramesThisCall) //make sure we don't execute unnecessary threads
{
if(isRealNumbers)
{
for(int i = 0; i < primitivesPerDataFrame; i++)
{
int inputArrayIndex = (gid*primitivesPerDataFrame)+i;
inputArray[inputArrayIndex] = inputArray[inputArrayIndex] * windowArray[i%windowSize];
}
}
else //complex
{
for(int i = 0; i < primitivesPerDataFrame; i++)
{
int inputArrayIndex = (gid*primitivesPerDataFrame)+i;
inputArray[inputArrayIndex] = inputArray[inputArrayIndex] * windowArray[i%windowSize/2];
}
}
}
}
我通常每块启动256个线程。我相信我的条件语句,如果isRealNumbers == true,那么我的warp在InputArray中访问一个128字节对齐的块。如果isRealNumbers == false,那么我的warp会在InputArray中访问两个128字节对齐的块?我觉得读取和写入请求的总数应该是1:1,包括读取和写入事务的总数。如果我没有看到什么东西,请分享,因为分析器不同意我:) – smuggledPancakes 2010-11-12 14:08:03
只需计算'primitivesPerDataFrame'> 1的一些示例的偏移量,您就会看到访问不是连续的,而是有一定的步伐迅速变得足够大,使不可能的联合。此外,您正在为真实和复杂数字执行完全相同的全局内存访问。 – dietr 2010-11-12 20:24:57
对不起,如果我是密集的,但我不明白我对inputArray的任何访问是不是连续的。你能解释一下吗? – smuggledPancakes 2010-11-15 14:19:32