3

我有一些使用几个大型 MEX 函数的 matlab 代码,我想通过使用 openCL 来加快速度(我正在使用 openCL API 用 openCL 代码替换 MEX 函数的部分代码)。我已经将一小部分代码翻译成 openCL 内核,但我已经面临困难。

在 GPU 上执行后得到的矩阵的某些元素与调用原始 MEX 函数时得到的矩阵的对应元素不同,并且误差小于 0.01。这会导致最终结果中出现一个小错误,但我担心当我翻译更多代码时错误会累积。

这可能与 CPU 和 GPU 的计算精度不同有关。有谁知道如何确保相同的精度?我在 Ubuntu 12.04 上运行 64 位 matlab R2012b。我使用的硬件是 Intel Core2 Duo E4700 和 NVIDIA GeForce GT 520。

4

2 回答 2

3

如果您将代码从在 CPU 上使用双精度(64 位)fp 数修改为使用单精度(32-位)GPU 上的 fp 数。

我不会将这种差异称为错误,而是在使用浮点数的计算机上进行算术运算的产物。您在纯 CPU 代码上获得的结果已经与任何理论上的“真实”结果不同。数值计算的大部分艺术是在整个计算期间保持理论计算和实际计算之间的差异足够小(不管这意味着什么)。这需要比我现在更多的时间和空间来扩展它,但是由于缺乏对浮点算术是什么和不是什么的理解而产生的惊喜是关于 SO 的丰富问题来源。这些问题的一些答案非常有启发性。 应该让你开始。

如果您注意在 CPU 和 GPU 上使用相同的精度,那么您报告的差异可能由浮点运算的非交换性来解释:在浮点运算中,不能保证(a+b)+c == a+(b+c). 操作顺序很重要;如果您正在进行任何 SIMD,我敢打赌这两个实现的操作顺序并不相同。即使你没有,你做了什么来确保 GPU 和 CPU 上的操作顺序相同?

至于你应该怎么做,这取决于你。您可以(尽管我个人不推荐)编写自己的例程来在 GPU 上执行双精度 fp 算术。如果您选择这样做,请期待与 GPU 承诺的大部分加速说再见。

更好的做法是确保您的单精度软件为您的目的提供足够的准确性。例如,在我工作的世界中,我们从环境中进行的原始测量通常不准确到超过 3 位有效数字,因此我们的代码产生的任何结果在大约 3 sf 之后都无效。因此,如果我可以将错误保持在第 5 个和更低的 s-fs 中,那就足够了。

double不幸的是,从您的角度来看,通过全局替换和重新编译不一定能保证从单精度计算中获得足够的准确性float,您可能(通常会)需要实现不同的算法,这些算法需要更多时间来保证更高的准确性和随着计算的进行,它们不会漂移太多。同样,您将失去一些 GPU 承诺的速度优势。

于 2013-01-09T11:01:30.680 回答
2

一个常见的问题是,浮点值保存在 80 位 CPU 寄存器中,而不是每次都被截断和存储。在这些情况下,额外的精度会导致偏差。因此,您可以检查您的编译器提供了哪些选项来解决此类问题。查看发布和调试版本的差异也很有趣。

于 2013-01-09T10:01:03.897 回答