关于programming guide中矩阵相乘的问题

在使用共享存储器的矩阵相乘中,最终只是将结果放到了shared memory中。

我想请问,如何才能把shared memory中的小矩阵的值传入global memory呢。

如果只是简单的每个线程写一个值,就应该不需要先写入shared再写入global吧。
(也许硬件会自动合并,一次写入global)

不知道这个是如何实现?

楼主您好,

(1)我们目前的所有显卡都不支持直接将shared memory中的值写入global memory的。
(2)您可以先读取global memory到寄存器中(普通变量)然后再将此变量写入到global memory的。
(3)关于您的简单每个线程写一个值得问题,您可以直接写入(实际上您根据1和2看出,就算你先写入shared memory的,也需要再从寄存器写入到global memory的。所以一般无需这么做。除非是为了将多个线程中的数据在shared memory中进行手工组合合并,然后再次读取写入global memory)

感谢来访。

第2条中,您应该是手误。我明白了。

手动合并问题我还不懂,不过等到时候自己学了有问题再请教你们。

谢谢您的耐心解释。

LZ您好:

我来稍微解释下手工合并的事情。

假定某算法下,你一个线程生成了最终需要存储在一行中的数据(这里用习惯上的行优先存储)。
那么此时,如果每个线程直接向global memory存储,那么一个warp的线程每次存储的时候,相邻线程的写入位置都离得非常远,这极大地影响存储效率。

此时可以将每个线程的生成数据都写到shared memory中,每个线程写一行,然后在适当同步之后,用一组线程去将shared memory中的一行数据写到global memory中,此时是合并访问的,访存效率较高。

大致如此,供您参考。

祝您好运~

这个真心不好意思,将shared打成了global。不过感谢楼主指正。

您的意思是,如果我的一个warp中的线程往global memory写入数据是连续的,那么硬件会进行一次 global memory 的访问,而如果不连续,就会访问32次是吗?

这个硬件的操作是由谁来完成的呢?

我问题的描述有个地方错误,为以免误导后来人,在此修正一下。

“在使用共享存储器的矩阵相乘中,最终只是将结果放到了shared memory中。”

其实并不是放在了shared memory中,是我自己理解错了。确实是每个线程往global memory中写一个值。而且应该是满足 ice 版主所说的合并访问的。

LZ您好:

您没有给出这个乘法算法实现的任何细节描述。

因此我无法也从来没有表示过您的实现是否满足合并访问的条件。

以及我4#的内容是在做“名词解释”,来补充横扫斑竹2#中的内容。

大致如此。

我指的就是 cuda_c_programming_guide 里面的使用共享存储器的矩阵相乘。

如果您觉得我盗用了您的名义来陈述自己的观点。我表示抱歉。下次我会注意措辞。

感谢您的耐心解释。

LZ您好:

global 访存是一个warp的线程整体通过SM中的硬件访问L2 cache以及global memory实现的。

如果访问是合并的(这需要所访问的数据集中在一定长度的显存范围之内,并且适当对齐),那么SM可以一次性获取所有所需数据。

如果不满足上述要求,比如前面说的相邻线程访问数地址距离很远,将分为多次访问完成,每次丢弃不需要的数据。但并非一定是32次。

大致如此。

LZ您好:

感谢您指明您的具体算法实现来源。

以及澄清若干事实。

祝您好运~

假设我一次访问的数据里面含有两个我所需要的数据,但是却不是连续的,会同时留下这两个数据吗?

LZ您好:

对于当前的主流GPU来说,会留下这两个数据的。

感谢您的耐心指导,以及您的刚正不阿的态度。印象非常深刻。