关于CUDA优化

斑竹你好,
我上次的帖子http://cudazone.nvidia.cn/forum/forum.php?mod=viewthread&tid=7228
根据您的指点找出了问题,tempdist_d = tempdist_d + (powf(GpuArray_d[i_d_d*AttributeN_d+j] - GpuArray_d[z_dAttributeN_d+j],2.0));中z_d是线程编号,一个warp中的临近两个线程访问访问的是不连续的存储空间(在我的问题中AttributeN=168),我试着删除z_d运行程序,果然速度是惊人的,但结果当然不对。
我需要计算n
m矩阵中每个行的所有元素和剩余行对等元素之间的的距离{如n(0,0)-n(1,0),n(0,1)-n(1,0)等等}
,至今我试过矩阵转置在内的一些办法,但转置后发现连个线程之间的元素相差50000(行数),还是未能实现优化,
真不知到怎么处理,能否再给处些建议或具体的思路?谢谢。

LZ您好:

1:您引用的原帖中各问题均已经有详细答复,请您直接参考,我并无补充。

2:访存无法合并只影响效率,不影响正确性。如果可以,请您考虑适当地改写您的代码以实现合并访问,而不是“删除z_d”,先保证正确性再考虑优化。一个结果错误的实现其速度没有任何意义。

3:未能理解“计算n*m矩阵中每个行的所有元素和剩余行对等元素之间的的距离{如n(0,0)-n(1,0),n(0,1)-n(1,0)等等}”请您给出具体叙述,以及说明什么是“对等元素”。

只有在您清楚地表达了实现意图之后,才能给您进一步的建议。

祝您好运~

我有50000行168列的矩阵。存入到指针数组。
我的计算意图是:
从数组中读取第1个元素(第一行第一元素),计算把它和第169个元素的欧氏距离,
下一步从数组中读取第2个元素,计算把它和第170个元素的欧氏距离,
下一步从数组中读取第3个元素,计算把它和第171个元素的欧氏距离,

从数组中读取第168个元素,计算把它和第326个元素(第一行最后一个元素)的欧氏距离,
到此第一行和第二行之间的举例计算结束,下一步是第一行和第三行。一直到第一行和最后一行。这样下来针对第一行的整个运算结束,
然后针对第二行的计算,算法和上一行一样,具体代码请参照我的原帖,
因为算法要求,我的程序中每个线程负责计算一行,这样相邻的线程之间168元素,这样下降效率。真希望能得到能满足合并访问的改进意见。

LZ您好:

根据您3#的补充说明,您的数据是行优先存储的(即169元素即是第二行第一个元素,第326个元素是您第二行最后一个元素)。

第一行的每个元素需要和这一列的其他行的元素分别计算欧氏距离。

(第二行等应与之类似,不再翻旧帖详细看了。)

那么这个访存的需求如果要合并访问实现,那么必须得是上一组线程,分别读取一行中的数据。
但是您指定了您的算法必须是一个线程读取一行的数据,那这样是无法满足合并访问要求的。

所以,您有必要修改您的算法实现。

您可以考虑将您之前一个线程处理一行改为一组线程处理一行,这样首先可以满足合并访问。如果各列的数据和计算中间结果还需要综合在一起处理,那么您还可以使用shared memory来实现这一组线程中的数据和结果的共享。

我估计您的算法完全可以使用上述的建议改写,并有不错的访存效率和计算效率。

祝您好运~

BLOCK_NUM=32 THREAD_NUM=168
我改了之后出错,结果有误,不知是哪里的问题,斑竹可否在看一看?
for (z =bidTHREAD_NUM+tid; z < Dataset_Dimension_d; z+=BLOCK_NUMTHREAD_NUM){
for (int y=0, j=z; j < BLOCK_NUM*THREAD_NUM ; y++, j+=BLOCK_NUM )
tempdist+=(powf(CurrentRow[y]-GpuArray[j],2.0));
tempdist = 0.0f;
}
}

LZ您好:

请您借助调试工具并结合您的具体报错情况予以调试。

斑竹不是神仙,无法在既不知道您的实现意图,又不知道您的错误情况,并且只有您截取的这几行代码的情况下,自动猜出您的问题并给出解答的。请您自重。