我有AMD GPU,我想实现'Matrix Transpose'示例。想象一下实现的两个场景:
1)
从全局内存(当前位置)读取
写入全局内存(目标位置)
2)
从全局记忆中读取(当前位置)
写入本地内存
从本地内存中读取
写入全局记忆(目标位置)
假设我为两种解决方案选择了最佳的工作组大小。 顺便说一句,第二个算法利用协作写入本地内存。
最后,令人惊讶的是,第二个场景的速度是第一个场景的两倍。我只是不明白为什么?
我可以看到在第一个中我们有1个读取和1个写入和来自全局内存,而在第二个中,除了全局内存操作之外,我们还有1个读取和1个写入本地内存,它怎么会更快?
如果有人在这种情况下帮助我,我会很高兴。
提前谢谢: - )
答案 0 :(得分:1)
我有AMD GPU,我想实现'Matrix Transpose'示例。
(万一你不知道,nVidia SDK包含一个OpenCL矩阵乘法示例(也许AMD APP也有),所以你以后可以将你的代码与他们的代码进行比较。)
第一个变体将不可避免地从顺序工作项中读取或写入具有非顺序存储器位置的矩阵元素。这意味着每个这样的访问都必须单独执行,并且由于全局内存访问具有显着的延迟,因此会降低代码的速度。
第二种变体利用了称为合并的功能。视频卡驱动程序可以将来自顺序工作项的多个内存请求连接到顺序存储器位置(有一些细微差别,请参阅编程指南以获取详细信息)到一个大请求中,然后一次读取8个浮点数。因此,不是8个长请求,而是只有一个请求,这会显着提高性能。
但是在矩阵乘法算法中,为了使您的全局内存访问顺序,您在一个工作项中处理的数据必须由另一个项目存储。这就是为什么你必须使用本地内存 - 你填充它,同步工作组,然后将其内容存储到全局内存 - 但是以不同的顺序,以便存储过程是顺序的。是的,它涉及对本地内存的一些额外读/写,但是它们的延迟要小得多,所以如果你合并足够的全局内存操作,你就会获得整体胜利。