比C#中的浮点运算快两倍

本文关键字:两倍 浮点运算 | 更新日期: 2023-09-27 17:48:53

我正在编写一个应用程序,它读取大型浮点数组并用它们执行一些简单的操作。我用的是花车,因为我认为它会比双打更快,但经过一些研究,我发现这个话题有些混乱。有人能详细说明一下吗?

比C#中的浮点运算快两倍

简单的答案是,"使用可接受结果所需的精度。"

您的一个保证是,对浮点数据执行的操作至少在表达式的最高精度成员中完成。因此,两个浮点的乘积至少要达到浮动精度,而一个float和一个double相乘至少要达到两倍精度。该标准规定,"[浮点]运算的执行精度可能高于运算的结果类型。"

考虑到.NET的JIT试图使您的浮点运算保持所要求的精度,我们可以查看英特尔的文档,以加快我们的运算速度。在英特尔平台上,您的浮点运算可能以80位的中间精度完成,并转换为所需的精度。

从英特尔的C++浮点运算指南1(抱歉只有死树)中,他们提到:

  • 使用单精度类型(例如,浮点),除非需要通过双精度或长双精度获得额外精度。更高精度的类型增加了内存大小和带宽要求。
  • 避免混合数据类型的算术表达式

最后一点很重要,因为您可以通过对float和double进行不必要的强制转换来降低速度,这会导致JIT代码在操作之间请求x87从其80位中间格式强制转换!

1.是的,它说C++,但C#标准加上CLR的知识让我们知道C++的信息应该适用于这种情况

我刚刚阅读了MCTS考试70-536的"Microsoft.NET Framework应用程序开发基础第二名",第4页(第1章)上有一条注释:

注意使用内置类型优化性能
运行时优化了32位整数类型(Int32和UInt32)的性能,因此将这些类型用于计数器和其他经常访问的积分变量。对于浮点运算,Double是最有效的类型,因为这些运算是由硬件优化的。

这是托尼·诺斯鲁普写的。我不知道他是否是权威,但我希望.NET考试的官方书籍应该有一定的分量。这当然不是高谈阔论。我只是想把它添加到这个讨论中。

几周前我介绍了一个类似的问题。最重要的是,对于x86硬件来说,浮点和双精度的性能并没有显著的差异,除非您受到内存限制,或者开始遇到缓存问题。在这种情况下,浮子通常具有优势,因为它们较小。

目前的英特尔CPU在80位宽的寄存器中执行所有浮点运算,因此实际计算速度不应在浮点和双倍之间变化。

如果加载&商店运营是瓶颈,那么浮动会更快,因为它们更小。如果在加载和存储之间进行大量计算,则应该大致相等。

还有人提到要避免float&double和使用这两种类型的操作数的计算。这是一个很好的建议,如果您使用任何返回doubles的数学库函数(例如),那么将所有内容保持为doubles会更快。

我正在编写一个光线跟踪器,用Color类的doubles替换float可以使我的速度提高5%。用替身替换Vectors浮点又快了5%!很酷:)

这与Core i7 920 有关

使用387 FPU算法,float对于某些长迭代操作(如pow、log等)的速度仅为两倍多(并且只有在编译器适当设置FPU控制字的情况下)。

使用压缩SSE算法,它会产生很大的不同。

Matthijs,

你错了。在现代处理器中,32位的效率远高于16位。。。也许不是内存方面的,但在有效性方面,32位是最好的选择。

你真的应该给你的教授更新一些更"最新"的东西。)

不管怎样,回答问题;float和double的性能完全相同,至少在我的英特尔i7 870上是这样(理论上)。

以下是我的测量值:

(我做了一个"算法",重复了10000000次,然后又重复了300次,得出了平均值。)

double
-----------------------------
1 core  = 990 ms
4 cores = 340 ms
6 cores = 282 ms
8 cores = 250 ms
float
-----------------------------
1 core  = 992 ms
4 cores = 340 ms
6 cores = 282 ms
8 cores = 250 ms

我一直认为,无论浮点还是双精度,处理器都是优化的或相同的。在我密集的计算中搜索优化(大量来自矩阵的结果,两个值的比较),我发现浮点运算的运行速度快了13%。

这让我很惊讶,但我想这是由于我问题的性质。在运算的核心部分,我不进行浮点和双精度之间的转换,我的计算主要是加法、乘法和减法。

这是在我的i7 920上,运行一个64位操作系统。

这表明浮点运算略快于双精度运算:http://www.herongyang.com/cs_b/performance.html

一般来说,任何时候对性能进行比较时,都应该考虑任何特殊情况,比如使用一种类型是否需要额外的转换或数据处理?这些加起来可能会掩盖像这样的通用基准。

浮点在32位系统上应该更快,但要对代码进行评测,以确保您优化的是正确的。