我正计划深入研究 OpenCL,并且一直在阅读(仅了解表面知识)OpenCL 的功能,但有几个问题。
假设我有一台 AMD Radeon 7750,还有另一台配备 AMD Radeon 5870 的计算机,并且不打算使用配备 Nvidia 卡的计算机。我听说针对特定设备优化代码会带来性能优势。优化到底意味着什么?从我读过的内容和一点点猜测来看,这听起来意味着以 GPU 喜欢的方式编写代码(通常不用担心它是 AMD 或 Nvidia 卡)以及以匹配的方式编写代码显卡处理内存(我猜这是特定于计算设备的?或者这只是特定于品牌的?)。
因此,如果我编写代码并针对 Radeon 7750 进行优化,我是否能够将该代码带到另一台装有 Radeon 5870 的计算机上,并且在不更改代码的任何部分的情况下,仍然保留合理的性能优势从优化?如果代码不起作用,更改部分代码是否只是一个小问题,或者是否涉及重写足够的代码,因此首先为 Radeon 5870 编写优化代码会是一个更好的主意.
最佳答案
如果没有有关您打算编写的算法和应用程序的更多信息,这个问题有点模糊。但我认为我可以为您提供一些高级策略,供您在为这两个不同平台开发代码时牢记。
Radeon 7750 的设计采用全新 Graphics Core Next架构,而您的 HD5780 是基于较旧的 VLIW5 (RV770) Architecture .
为了让您的代码在 HD5780 硬件上良好运行,您必须尽可能大量使用打包的原始数据类型,尤其是 int4
、float4
类型。这是因为 OpenCL 编译器很难自动发现并行性并将数据打包到宽向量中。如果您可以构建代码以便已经考虑到这一点,那么您将能够填充更多的 VLIW-5 插槽,从而使用更多的流处理器。
这是一个过于简单的示例来说明我的观点:
// multiply four factors
// A[0] = B[0] * C[0]
// ...
// A[3] = B[3] * C[3];
float *A, *B, *C;
for (i = 0; i < 4; i ++) {
A[i] = B[i] * C[i];
}
该代码可能会在 GCN 架构上正常运行(除了次优的内存访问性能——一个高级主题)。但在 HD5870 上,这将是一场灾难,因为这四次乘法将占用 4 个 VLIW5 指令,而不是 1 个!因此,您可以使用 float4
类型编写上面的代码:
float4 A, B, C;
A = B * C;
而且它在您的两张卡上都运行得非常好。另外,它会在 CPU OpenCL 上下文中发挥出色,并充分利用 MMX/SSE 宽寄存器,这是一个额外的好处。这也是对内存系统的更好利用。
简而言之,当您开始同时在这两个系统上部署代码时,我建议您记住使用打包原语。
这里还有一个示例,可以更清楚地说明您在 HD5870 上进行操作时需要小心的事项。假设我们使用单独的工作单元实现了前面的示例:
// multiply four factors
// as separate work units
// A = B * C
float A, B, C;
A = B * C;
我们有四个独立的工作单位,而不是一个。这对 VLIW 设备来说绝对是一场灾难,但在 GCN 设备上会显示出更好的性能。当您编写代码时,您还需要考虑这一点——您可以使用 float4 类型来减少执行相同工作的工作单元的数量吗?如果是这样,那么您将在两个平台上看到良好的性能。
关于parallel-processing - Radeon 显卡之间 OpenCL 的移植和优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12500079/