0

我有一个 CUDA 应用程序,我为发布版本编译了两次:一次带有调试信息(使用 -G),一次没有调试信息。我运行对浮点数进行一些计算的应用程序(包括诸如 expf、sinf、cosf 等函数)。我注意到两个版本创建的数字略有不同,这里它们是并排的:

0: (-8.000000,0.000000,0.000000)        0: (-8.000000,0.000000,0.000000)
1: (-8.212574,-0.112065,0.970697)       1: (-8.212575,-0.112065,0.970697)
2: (-8.365530,-0.250361,1.949206)       2: (-8.365531,-0.250361,1.949206)
3: (-8.332600,-0.251884,2.948662)       3: (-8.332601,-0.251885,2.948662)
4: (-8.593035,-0.619825,3.841295)       4: (-8.593036,-0.619826,3.841295)
5: (-8.507285,-0.778658,4.824870)       5: (-8.507286,-0.778658,4.824870)
6: (-8.441058,-1.001207,5.797539)       6: (-8.441058,-1.001207,5.797539)
7: (-8.680929,-1.051136,6.767059)       7: (-8.680929,-1.051136,6.767059)

这些是前 7 个值(两个版本都以 -8,0,0 开头)。正如您在这一点上看到的,小数点后第 6 位只有很小的差异。但是,我在旋转矩阵计算过程中使用了这些,因此在其中 1000 次之后,差异加起来非常显着。

我没有添加源代码,因为它非常大而且非常复杂。

我想知道为什么首先会有差异。我知道调试版本和发布版本在优化方面存在巨大差异。我想有和没有调试信息的版本之间存在类似的差异。但是,优化如何改变计算精度?

4

1 回答 1

2

浮点运算不是关联的,因此运算顺序很重要。如果您更改编译器选项(例如有/无调试),编译器发出的代码可以而且通常是相当不同的。像重新排序一些浮点指令这样简单的事情就足以改变结果。

唯一确定的方法是查看设备上运行的最终代码。NVIDIA 提供了一个工具cuobjdump,您可以使用它来反汇编 CUDA 目标代码。如果您对两种方式中的每一种编译的内核进行并排比较,则可能会发现对于给定输入,两个浮点结果的差异出现在哪里。

于 2013-09-11T11:14:32.773 回答