如果您将代码从在 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 承诺的速度优势。