当我在GPU上划分两个浮点数时,结果为0.196405
。当我在CPU上划分它们时,结果为0.196404
。使用计算器的实际值为0.196404675
。如何在GPU和CPU上进行划分?
答案 0 :(得分:9)
正如对另一个答案的评论所表明的那样,有很多原因导致在CPU和GPU上运行浮点计算的相同结果是不现实的。它比这强得多:当相同的源代码针对不同的目标架构(例如x86或x64)或不同的优化级别进行编译时,你不能假设FP结果是相同的。
实际上,如果您的代码是多线程的,并且FP操作从一次运行到下一次运行以不同的顺序执行,那么在EXACT SAME SYSTEM上运行的EXACT SAME EXECUTABLE可能会产生从一次运行到下一次运行的稍微不同的结果。
其中一些原因包括但不限于:
请注意,出于本次讨论的目的,CUDA的JIT编译器(使PTX代码能够在未来可用的GPU架构中具有前瞻性的魔力)当然应该会扰乱FP结果。
尽管如此,你还是必须编写健壮的FP代码。
正如我今天写的那样,我相信CUDA GPU的浮点运算架构要比任何现代CPU都要好得多。 GPU包括原生IEEE标准(c.2008)对16位浮点和FMAD的支持,对非正规数有全速支持,并且能够在每个指令的基础上启用舍入控制,而不是控制其设置对所有FP指令有副作用的字并且变化很昂贵。
相比之下,CPU使用每线程状态过多且性能不佳,除非使用SIMD指令,主流编译器在利用性能方面很糟糕(因为使用标量C代码来利用这些指令集要困难得多)而不是为伪标量体系结构(如CUDA)构建编译器。如果要相信维基百科History页面,那么英特尔和AMD似乎已经完全拙劣地添加了FMAD支持,其方式无法描述。
您可以在此处找到关于浮点精度和NVIDIA GPU中IEEE支持的出色讨论:
答案 1 :(得分:1)
你没有。您永远不应该假设浮点值将完全等于数学运算后的预期值。它们仅被定义为对指定的精度是正确的,并且在处理器与处理器之间略有不同,无论该处理器是CPU还是GPU。例如,x86处理器实际上将默认执行具有80位精度的浮点计算,然后将结果截断为所请求的精度。浮点数的等效性比较应始终使用容差,因为不能保证任何两个处理器(或者甚至相同的处理器通过不同但数学上等效的指令序列)将产生相同的结果。例如。当且仅当|时,浮点数a和b应被视为相等a - b | <为了一些容忍度。
答案 2 :(得分:1)
哪个GPU用于计算?
如果使用单精度浮点运算,通常在尾数部分的第六位会有+ 1 / -1的精度误差。这是因为GPU中的四舍五入错误。
如果您使用双精度,您将获得在CPU中获得的精确精度。但速度几乎是浮点精度的一半,内存使用量将是2倍。 现在从基于FERMI的架构开始,NVIDIA GPU支持双精度点计算支持。