Viv*_*nda 13 c c++ optimization scientific-computing gsl
我们需要通过在C/C++中实现特定算法来解决的大多数科学计算问题要求精度远低于双精度.例如1e-6,1e-7精度覆盖99%的情况下,对ODE求解或数值积分.即使在我们确实需要更高精度的极少数情况下,通常数值方法本身也会在我们梦想达到接近双精度的精度之前失败.示例:即使在求解标准nostiff常微分方程时,由于舍入误差,我们也不能期望简单Runge-Kutta方法的1e-16精度.在这种情况下,双精度要求类似于要求更好地逼近错误答案.
然后,在大多数情况下,积极的浮点优化似乎是一个双赢的局面,因为它使您的代码更快(更快!)并且它不会影响您的特定问题的目标准确性.也就是说,确保特定的实现/代码对fp优化是稳定的似乎非常困难.古典(有点令人不安)的例子:GNL,GNU科学图书馆,不仅是市场上的标准数字图书馆,而且它是一个写得很好的图书馆(我无法想象自己做得更好).但是,GSL对fp优化不稳定.实际上,例如,如果使用intel编译器编译GSL,那么除非-fp-model strict打开关闭fp优化的标志,否则其内部测试将失败.
因此,我的问题是:是否存在编写代码的一般准则,这些代码对于积极的浮点优化是稳定的.这些指南语言(编译器)是否具体.如果是这样,那么C/C++(gcc/icc)的最佳实践是什么?
注1:这个问题不是询问gcc/icc中的fp优化标志是什么.
注2:这个问题不是询问有关C/C++优化的一般指导原则(比如不要将虚函数用于大量调用的小函数).
注3:这个问题不是要求大多数标准fp优化列表(如x/x - > 1).
注4:我坚信这不是类似于传统的"最酷的服务器名称"的主观/偏离主题的问题.如果您不同意(因为我没有提供具体的示例/代码/问题),请将其标记为社区维基.我对答案比对获得一些状态点更感兴趣(不是它们不重要 - 你明白了!).
Pas*_*uoq 13
编译器制造商-ffast-math通过断言这些优化对数值稳定算法的影响很小,证明了这种优化的合理性.
因此,如果要编写对这些优化具有鲁棒性的代码,则充分条件是只编写数值稳定的代码.
现在你的问题可能是,"我如何编写数值稳定的代码?".这是你的问题可能有点广泛的地方:有完整的书籍专门讨论这个主题.我已经链接到的维基百科页面有一个很好的例子,这是另一个好的例子.我不能特别推荐一本书,这不是我的专业领域.
注1:数值稳定性的可取性超出了编译器优化.如果您有选择,即使您不打算使用-ffast-math-style优化,也要编写数值稳定的代码.即使使用严格的IEEE 754浮点语义进行编译,数值不稳定的代码也可能提供错误的结果.
注意2:使用-ffast-math-style标志编译时,不能指望外部库工作.这些由浮点专家编写的库可能需要使用IEEE 754计算的属性进行微妙的技巧.这种技巧可能会被-ffast-math优化打破,但它们提高性能的程度超过了编译器的预期,即使你已经放弃了.对于浮点计算,具有领域知识的专家每次都会击败编译器.许多例子中有CRlibm中的三重双重实现.如果未使用严格的IEEE 754语义编译,则此代码会中断.编译器优化打破的另一个更基本的算法是Kahan求和:当使用不安全的优化编译时,c = (t - sum) - y优化为c = 0.当然,这完全违背了算法的目的.
| 归档时间: |
|
| 查看次数: |
1683 次 |
| 最近记录: |