误差问题

各位好。有两个问题请教大家。
一,有人指出,cpu gcc编译器-o3的优化选项,相对于gpu的nvcc的编译优化而言,其优化程度保守很多,请各位帮助分析这一观点,并给出具体原因。

二,我在fermi gpu上并行了一个科学计算程序,迭代计算一万步发现有百分之零点几的数值误差,经过仔细检查和分析,并没发现有程序上的错误,请问这个误差的大小是否在正常范围?是否可能由我的并行程序有未发现的bug而引起?

LZ好。您的两个问题答复如下:

一,有人指出,gcc编译器对cpu代码的编译优化选项,和nvcc对gpu代码的编译优化,完全是不具可比性的两个问题,因此无法比较。请LZ思考并评估这一结论,并给出具体感想。

二,您提出过相同的问题,并被详细地解答了。原帖地址如下:http://cudazone.nvidia.cn/forum/forum.php?mod=viewthread&tid=6462&extra=page%3D5
避免您盲目寻找。
请珍惜他人的劳动成果,不要重复发帖询问同样的事情。

大致如上,祝您好运~

你好。

第一个编译优化的问题,从影响计算结果的角度上是否可探讨?我曾经读到一篇论文谈及cpu编译选项对计算结果的影响,但并不太了解gpu方面的知识。

第二个问题较之前的问题有一些区别,这里想请教迭代一万步的情况下 百分之零点几 这样的一个误差量级是不是属于正常范围?还是我的程序可能有潜在的错误?

希望得到您的建议。

1:您读到的论文的关于CPU的结论请找论文作者讨论,以及您在顶楼谈及的“有人指出”请找“有人”讨论。
在此我重申一遍,这两个是不具可比性的。
以及您说的这个GPU编译选项对结果的影响,可以参考CUDA C Programming Guide,里面有各个数学函数的结果的精度情况,以及使用fastmath的时候,精度情况如何。

2:所有建议都在之前的链接里面给出了。
您的误差情况和您的算法有关,和您的算法有无积累误差有关,和您的算法使用何种精度的数据有关,和您的编译选项有关等等。以及,浮点数本身不具备计算的交换性和结合性,以及,您用于作对比的结果也只是一种情况下浮点数的结果,并非是真值。
所以,只能如前帖中一样建议您做相应的减少计算误差的做法。

但无法根据您一句话“迭代一万步,相差百分之零点几”为您分析出您的问题是程序BUG还是其他原因。

如果您真的需要该结论,请自行研究分析,或者向当地的神咨询。

大致如此,祝您好运~

出现误差是很正常的,并且排除程序BUG的情况下,0.x%的误差是在可接受范围内的!比如浮点数计算时,A+B+C != C+B+A,这样就会产生一些微小的误差!

谢谢各位。

找到了原因,现在误差竟全消。。

“找到了原因,现在误差竟全消。。”

楼主不要为了面子而这么说,回帖中的解答都是为了您尽量解决问题。
取得GPU和CPU,在float上,一般情况是不会相同的。

以及如果您真的发现了解答不对,请回馈论坛,以帮助其他读者或者督促版主们改正自己的错误认识。
如果您发现的某种让GPU和CPU完全一致的方法,请告诉论坛,而不是自己说一句“我发现了方法,误差竟然全消除”。

感谢您的周末来访。

您好,谢谢您的解答。

现在确实如此,并非“为了面子”。。而且我也感到很奇怪,难道这和Fermi采用的IEEE浮点标准有关?

我的算法里倒也确实没有楼上说的结合律问题,也没有使用任何快速数学计算函数,出的问题是在另一个帖子“关于最小值规约”里,如您有经验帮助解答,请移步。

楼主您好,看了您的求最小值的帖子。但是我不认为您的这个帖子和您的6#有任何关系。

以及,此帖子ICE已经给予了详细的正确的解释了。

请就地解释。

您好。

就结果看:在迭代1w步之后对比某项结果,发现小数点后到第十位均保持了一致,之后几位有效位我倒是并没有一一查对,直接量化计算也没有发现误差,而造成这一结果改变的,就只有这个规约最小值的同步问题了。

我认为这也许算法和几位之前的建议相符有关,即:
1.没有结合律问题
2.没有任何快速数学函数

您的意思是完全没有误差是不正常的表现?非常乐意和您探讨这个问题,也希望您所遇到的误差情况案例。

既然您的计算是另外一个问题的“求最小值”,那么我不认为这个问题能带来“误差”。

因为它属于比较大小和普通读写,这个过程不会引入任何误差。
最小值要么求的完全正确,要么就是错误,而不是误差。

以及你之前说是“一万步的科学计算”。那么这个才有可能是“误差”。

我不明白你将2个帖子混合起来的目的是什么。

但求最小值和普通计算,我已经将观点上述在上述段落了。

我再重复一遍:
(1)“求最小值,结果要么是正确要么是错误”。
(2)普通的运算,才可能和CPU结果不同。

然后继续补充说一下,

ICE大大曾经说过,在CPU计算浮点数有x87和SSE等多种方式。

x87可为float运算提供最高的80-bit的中间结果。此时比GPU的float的结果更为精确是有可能的。
以及,
sse运算float, 反而可能不如GPU精确,因为SSE它没有乘加,中间结果不如GPU的FMA精确了。

那么无论是CPU使用上述2种计算指令的那一种,你可以看出,想和GPU取得完全一致的结果概率较小了。这也是我之前想让您回馈论坛下,如何能取得您说的“完全一致的结果“的原因。

当然,如果您的”一万步的科学计算“是求最小值,这个除外(详上楼层)

确实是错误,而不是误差,只不过这个错误我一直没有发现。

由于这个错误的计算结果偏差很小,所以导致我一直认为是计算误差导致的。

至于您提到的完全一致概率很小的问题,我如果接下来的工作有所发现,一定回馈论坛。

再次感谢。

感谢来访。欢迎常来!