如果更喜欢使用-ffast-math,则哨兵值较高,可以加倍 [英] Good sentinel value for double if prefer to use -ffast-math

查看:61
本文介绍了如果更喜欢使用-ffast-math,则哨兵值较高,可以加倍的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于 gcc 选项 -ffast-math 有效地禁用了 NaN -/+ inf ,因此我我正在寻找对性能至关重要的数学代码中表示 NaN 的下一个最佳选择.理想情况下,如果对哨兵值进行操作(添加,mul,div,sub等),将产生哨兵值,就像 NaN 一样,但是我怀疑这样做是否可行,因为我认为 NaN是完成此操作的唯一值. -0.0 可能不是一个很好的选择,因为它也已在 -ffast-math 中禁用,并且可能会阻止某些优化,例如(x + 0.0),等等.

Since the gcc option -ffast-math effectively disables NaN and -/+inf, I'm looking for maybe the next best option for representing NaN in my performance-critical math code. Ideally the sentinel value if operated on (add, mul, div, sub, etc..) would yield the sentinel value as NaN would do but I doubt this would be possible since I think NaN is the only value that accomplishes this. -0.0 might not be a good fit as it's also disabled in -ffast-math and could prevent certain optimizations like (x+0.0), etc..

也许我的问题应该是,有什么方法可以使用 NaN 或其他特殊双精度",同时又能够启用许多数学优化而不会发生故障?

Perhaps my question should rather be, is there any way to use NaN or some other "special double" while being able to enable a lot of the math optimizations without breaking down?

系统是 Linux/x64,gcc 4.8.1 .

推荐答案

如果您正在寻找可以通过算术运算传播的值,则 NaN 仍可与选项 -ffast一起使用.-数学.问题出在其他地方.使用 -ffast-math 可以通过优化将某些操作从计算中删除,然后就无法保证 NaN 或任何其他值都会传播.

If you are looking for a value which would be propagated by arithmetic operations, NaN is still available with option -ffast-math. The problem lies somewhere else. With -ffast-math some operations can removed from the computation due to optimization, and then there is no way to guarantee NaN or any other value would be propagates.

例如,以下设置了 -ffast-math 的代码将导致将 0.0 硬写到 n 中,并且没有特殊值为 n 提供保护.

For example, the following, with -ffast-math set, will cause hard writing 0.0 into n and there is no special value for n which would protect from it.

float n = NAN;
n *= 0.0;

您可以做的一件事是,如Shafik Yaghmour所说,将 -fno-finite-math-only -ftrapping-math -ffast-math 一起使用.另外,如果只有少数几个地方您期望有一个不好的值,那么您可以自己对这些点进行准确的测试来进行检查.

One thing you can do, is to use -fno-finite-math-only -ftrapping-math with -ffast-math as Shafik Yaghmour said. And the other is, if there are only few places where you expect a bad value, you can check for it by yourself putting tests exactly in those points.

我认为的最后一个选择-如果您确实非常需要优化-是将 NaN (可能还有 inf )值手动注入到计算中,并检查是否它传播了多长时间.然后,在传播停止的那些地方,测试 NaN ( inf )的发生.-这是一种不安全的方法,因为我不确定百分之一百可以 -ffast-math 涉及条件操作流.如果可以的话,则有很大的机会,此解决方案将无效.因此这是有风险的,如果选择,则需要涵盖计算所有分支的非常繁重的测试.

The last option I can think -- if you really badly need optimization -- is to manually inject NaN (and maybe inf) values into the computation and check for how long it is propagated. Then in those places where the propagation stops, test for NaN (inf) occurrence. -- This is an unsafe method, as I am not one hundred percent sure, can -ffast-math involve conditional flow of operations. If it can, there is a significant chance, this solution will be invalid. So it is risky and if chosen needs very heavy testing covering all branches of the computation.

通常我宁愿反对最后一个解决方案,但实际上有机会将 NaN ( inf )值传播到整个计算或几乎整个计算中,因此它可以提供您想要的性能.因此,您可能要冒险.

Normally I would be rather against the last solution, but actually there is a chance, NaN (inf) values will be propagated though the whole computation or almost whole, so it can give the performance you are seeking for. So you may want to take the risk.

可以使用 -ffast-math 检查 NaN ,就像Shafik Yaghmour所说的那样,

Checking for NaN with -ffast-math you can do, as Shafik Yaghmour said, with

inline int isnan(float f)
{
    union { float f; uint32_t x; } u = { f };
    return (u.x << 1) > 0xff000000u;
}

,对于 double

inline int isnan(double d)
{
    union { double d; uint64_t x; } u = { d };
    return (u.x << 1) > 0xff70000000000000ull;
}

检查 inf

inline int isinf(float f)
{
    union { float f; uint32_t x; } u = { f };
    return (u.x << 1) == 0xff000000u;
}

inline int isinf(double d)
{
    union { double d; uint64_t x; } u = { d };
    return (u.x << 1) == 0xff70000000000000ull;
}

您还可以合并 isnan isinf .

这篇关于如果更喜欢使用-ffast-math,则哨兵值较高,可以加倍的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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