我最近在用cuda改一个程序,其中有一个步骤为了节省时间,使用了几万个单浮点数相加再相减的的方法。但是发现小数点后第六位出现了一点点偏差。然后整个程序的结果就差很大。 我是用硬件的计算能力是1.1.无法支持双浮点数的计算。 求教 有什么方法? 可以减掉这个误差吗?(除了双浮点!!)
其实无外乎两个方法:
1:修改算法,改为精度不敏感的,或者改变一些浮点数的计算顺序,避免丢失精度。具体方法一些计算方法的书上有讲。不过估计此法有一定难度。
2:换卡,换fermi核心的或者kepler核心的,这两个核心的GPU支持IEEE 754 2008标准的浮点计算,精度比1.x的卡好,或许可以解决这个问题。如果此时单精度仍然不能满足要求,那么只能上双精度了,您说呢?
欢迎莅临cudazone,祝您编码愉快!
另外,如果只是小数点后第六位有一点点偏差,就能使得结果偏差很大。
那么您的算法非常依赖于精度而并不是很稳定,这一点也请您考虑。因为一般来说,即使计算过程不出现偏差,而是原始数据有一点点偏差,造成小数点后第六位的改变,也会显著地影响您的结果。
如果您几万个相加的数可以预知那些是较大的数,那些是较小的数,那么将较大的放在一起相加,较小的放在一起相加,最后再合并,这样比较不容易丢失精度,防止“大数吃掉小数”。
祝您编码愉快。
唉 换卡是没戏了 现在的卡还是找了很久才找出来的 不过“大数吃小数” 在单精度的加法中 您说的是越界(超出数值最大范围)吗?
不是的,这个一般计算方法的书上都会讲。您也可以参考下面的链接里的内容。
http://blog.csdn.net/zhangpinghao/article/details/8197600
http://www.cnblogs.com/mphyfin/archive/2011/10/28/2227616.html
http://www.tyut.edu.cn/kecheng/jisff/kcnr1-5.html
(上述链接均为google查询 “浮点数 大数吃掉小数”得到)
另外,找一个fermi架构渣卡做做实验就行了,不是很贵的,BOSS应该会批准的。
祝您编码愉快。
或者您也可以参加您当地的CUDA沙龙(如果有的话),试试手气如何,运气好的话可以抽奖抽到一个CUDA开发者入门套装,内含GTX480一块和参考教程一本。
具体举办情况请参考本论坛“官方活动”板块,超版 朱潜羲 的帖子。
祝您好运!
嗯嗯 好的 谢谢您的回答 收益良多 :lol
:3_48::3_48::3_48:
对于计算能力为1.x的设备,由于部分指令并非是标准IEEE,所以计算所得的结果与使用标准IEEE是有区别的。解决方法就是ICE提到的可以换fermi核心的卡,在fermi核心上就不存在这个问题了,当然如果精度不够用了,只能用双精度来解决这个问题了!
对了,还想起来一点,您可以先使用CPU试验下单精度浮点数,这么相加,相减之后精度如何,如果CPU实现下精度也不满足,那么您可得好好改改实现或者用双精度了。
如果CPU下单精度这样做效果还可以,您可以试试直接上fermi核心的卡,可能就不用修改实现而直接满足要求。
依据IEEE-754标准,单精度浮点的十进制表示只有6-7位有效数字,所以您的结果中第六位出现了一点点误差应该是可以理解的。
另外:如果精度真的非常重要的话,建议楼主试试会排序然后再相加。如果数据都是正和负的话,也建议楼主使用reduction算法,reduction能够提供比对应的串行算法更高的精度。