浮点优化-准则 [英] Floating-point optimizations - guideline

查看:117
本文介绍了浮点优化-准则的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们需要通过在C/C ++中实现特定算法来解决的大多数科学计算问题所要求的精度远低于双精度.例如,1e-61e-7精度涵盖了ODE求解器或数值积分情况的99%.即使在极少数情况下确实需要更高的精度,通常数值方法本身也会在我们梦想达到接近双精度的精度之前就失败了.示例:即使由于舍入误差而求解标准的nostiff常微分方程,我们也无法从简单的Runge–Kutta方法获得1e-16精度.在这种情况下,双精度要求类似于要求更好地近似错误答案.

The majority of scientific computing problems that we need solve by implementing a particular algorithm in C/C++ demands accuracy that are much lower than double precision. For example, 1e-6, 1e-7 accuracy covers 99% of the cases for ODE solvers or numerical integration. Even in the rare cases when we do need higher accuracy, usually the numerical method itself fail before we can dream of reaching an accuracy that is near double precision. Example: we can't expect 1e-16 accuracy from a simple Runge–Kutta method even when solving a standard nostiff ordinary differential equation because of roundoff errors. In this case, the double precision requirement is analogous of as asking to have a better approximation of the wrong answer.

那么,在大多数情况下,积极的浮点优化似乎是一种双赢的情况,因为它可以使您的代码更快(更快!),并且不会影响特定问题的目标准确性.也就是说,要确保特定的实现/代码对于fp优化是稳定的,似乎非常困难.经典(有些令人不安)的示例:GNU科学图书馆GSL,不仅是市场上的标准数字图书馆,而且还是一个编写得很好的图书馆(我无法想象自己做得更好).但是,GSL对于fp优化不稳定.实际上,例如,如果使用intel编译器编译GSL,则除非您打开-fp-model strict标志(这会关闭fp优化),否则它的内部测试将失败.

Then, aggressive float point optimizations seems to be a win-win situation in most cases because it makes your code faster (a lot faster!) and it does not affect the target accuracy of your particular problem. That said, it seems remarkable difficult to make sure that a particular implementation/code is stable against fp optimizations. Classical (and somewhat disturbing) example: GSL, the GNU scientific library, is not only the standard numerical library in the market but also it is a very well written library (I can't imagine myself doing a better job). However, GSL is not stable against fp optimizations. In fact, if you compile GSL with intel compiler, for example, then its internal tests will fail unless you turn on -fp-model strict flag which turn off fp optimizations.

因此,我的问题是:是否存在编写针对攻击性浮点优化稳定的代码的一般准则.这些准则语言(编译器)是否专用?如果是这样,那么C/C ++(gcc/icc)最佳做法是什么?

Thus, my question is: are there general guidelines for writing code that is stable against aggressive floating point optimizations. Are these guidelines language (compiler) specific. If so, what are the C/C++ (gcc/icc) best practices?

注1:这个问题不是在问gcc/icc中的fp优化标志是什么.

Note 1: This question is not asking what are the fp optimizations flags in gcc/icc.

注2:这个问题不是在询问有关C/C ++优化的一般准则(例如,不要将虚函数用于被称为很多的小函数).

Note 2: This question is not asking about general guidelines for C/C++ optimization (like don't use virtual functions for small functions that are called a lot).

注3:此问题不是询问大多数标准fp优化的列表(例如x/x-> 1).

Note 3: This question is not asking the list of most standard fp optimizations (like x/x -> 1).

注4:我坚信这不是类似于经典最酷的服务器名称"的主观/题外问题.如果您不同意(因为我没有提供具体的示例/代码/问题),请将其标记为社区Wiki.我对答案更感兴趣,而不是获得一些状态积分(不是很重要-您明白了!).

Note 4: I strongly believe this is NOT a subjective/off-topic question similar to the classical "The Coolest Server Names". If you disagree (because I am not providing a concrete example/code/problem), please flag it as community wiki. I am much more interested in the answer than gaining a few status points (not they are not important - you get the point!).

推荐答案

编译器制造商断言,这些优化对

Compiler makers justify the -ffast-math kind of optimizations with the assertion that these optimizations' influence over numerically stable algorithms is minimal.

因此,如果您要编写对这些优化具有鲁棒性的代码,则充分的条件是仅编写数值稳定的代码.

Therefore, if you want to write code that is robust against these optimizations, a sufficient condition is to write only numerically stable code.

现在您的问题可能是如何编写数值稳定的代码?".这是您的问题可能涉及的范围很广的地方:有一本专门针对该主题的整本书.我已经链接到的Wikipedia页面上有一个很好的例子,此处是另一个很好的例子.我不能特别推荐一本书,这不是我的专长.

Now your question may be, "How do I write numerically stable code?". This is where your question may be a bit broad: there are entire books dedicated to the subject. The Wikipedia page I already linked to has a good example, and here is another good one. I could not recommend a book in particular, this is not my area of expertise.

注1:数值稳定性的要求超出了编译器的优化范围.如果可以选择,即使您不打算使用-ffast-math样式的优化,也可以编写数值稳定的代码.即使使用严格的IEEE 754浮点语义进行编译,数值不稳定的代码也可能会提供错误的结果.

Note 1: Numerical stability's desirability goes beyond compiler optimization. If you have choice, write numerically stable code even if you do not plan to use -ffast-math-style optimizations. Numerically unstable code may provide wrong results even when compiled with strict IEEE 754 floating-point semantics.

注2:使用-ffast-math样式的标志进行编译时,您不能期望外部库能够正常工作.这些由浮点专家编写的库可能需要发挥IEEE 754计算属性的微妙技巧. -ffast-math优化可能会破坏这种技巧,但是即使您允许,它们也可以比您期望的编译器更好地提高性能.对于浮点计算,具有领域知识的专家每次都会击败编译器.在许多示例中,有一个在 CRlibm 中找到的三重实现.如果未使用严格的IEEE 754语义编译该代码,则该代码将中断.编译器优化会破坏的另一个更基本的算法是 Kahan求和:使用不安全的优化进行编译时,c = (t - sum) - y会优化为c = 0.当然,这完全破坏了算法的目的.

Note 2: you cannot expect external libraries to work when compiled with -ffast-math-style flags. These libraries, written by floating-point experts, may need to play subtle tricks with the properties of IEEE 754 computations. This kind of trick may be broken by -ffast-math optimizations, but they improve performance more than you could expect the compiler to even if you let it. For floating-point computations, expert with domain knowledge beats compiler every time. On example amongst many is the triple-double implementation found in CRlibm. This code breaks if it is not compiled with strict IEEE 754 semantics. Another, more elementary algorithm that compiler optimizations break is Kahan summation: when compiled with unsafe optimizations, c = (t - sum) - y is optimized to c = 0. This, of course, defeats the purpose of the algorithm completely.

这篇关于浮点优化-准则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆