【问题标题】:floating point arithmetic in gnuradiognuradio中的浮点运算
【发布时间】:2018-06-23 14:22:56
【问题描述】:

我正在尝试了解 GNURadio 中的浮点运算并开始研究他们的测试。测试生成随机浮点输入和随机抽头,然后将所有内容传递给过滤器。稍后它会使用一些边距比较预期输出和实际输出。

有一条关于margin的神秘评论:

    // we use a sloppy error margin because on the x86 architecture,
    // our reference implementation is using 80 bit floating point
    // arithmetic, while the SSE version is using 32 bit float point
    // arithmetic.

我在源代码中找不到任何 80 位算术。谁能帮我?或者只是解释为什么误差范围取决于抽头大小?

【问题讨论】:

  • 我相信 x87 浮点架构的内部精度是 80 位 - 请参阅 en.wikipedia.org/wiki/…
  • @OliverCharlesworth:一些 (Win32) 编译器也允许您使用扩展(80 位)精度,如 long double

标签: c++ floating-point gnuradio


【解决方案1】:

在 x86+87 上,即使简单地使用 double,您也可以获得 80 位精度的中间结果,因为 FPU 堆栈在内部使用 80 位浮点数。

如果您的代码期望并依赖于 64 位或 32 位浮点数学的舍入,您会得到惊喜。

例如,x < y 是真的,但在分配 z = x 之后,您可能会得到 z >= y(所有变量都声明为 double)。如果 x 最终被分配到 80 位 FPU 寄存器中,而 z 是内存中的真正 64 位浮点变量,则可能会发生这种情况。

g++ 有一个特定选项可以避免这些问题 (-ffloat-store),它会阻止使用额外的位(但会大大降低数学密集型代码的速度)。

【讨论】:

    【解决方案2】:

    注意:根据下面Marcus Müller 的评论,GNURadio 已经有一段时间没有使用 80 位浮点了,所以问题中引用的评论充其量是陈旧的。所以这个答案通常只说明 80 位和 32 位浮点运算之间的差异,不适用于当前的 GNURadio 实现。

    您没有显示源代码,所以答案是推测性的。据推测,参考实现使用了long double,而作者使用的C++实现中的long double是用Intel硬件内置的80位浮点类型实现的。从任何显式扩展精度算术的意义上来说,它看起来不像 80 位代码;它看起来就像带有 long double 类型的 C++ 代码。

    同时,主要实现是使用 SSE 代码实现的。 SSE 是 Intel 指令子集的名称,其中包括一次处理四个 32 位浮点数的 SIMD(单指令多数据)指令。该代码在外观上很明显;它可以在汇编中使用 SSE 指令,在 C++ 中使用引用 SSE 指令的编译器内置函数,或者在 C++ 中使用编译器扩展来支持向量类型。

    自然,使用 32 位浮点运算时出现的浮点舍入误差与使用 80 位浮点运算时出现的浮点舍入误差不同,因此人们不会期望计算结果为两种不同的方法要相等。作者设计的测试可以容忍结果的一些差异。

    需要注意的是,虽然代码当然是针对 Intel 架构的,但并不是所有的 C++ 实现都使用 80 位浮点运算实现 long double。 C++ 实现可能使用 64 位算术。因此,如果您使用与作者不同的 C++ 实现来运行代码,您可能会得到不同的结果。虽然 64 位算术通常比 80 位算术具有更大的舍入误差,但作者为 32 位和 80 位算术之间的差异设置的任何容差很可能也会涵盖 32 位和 64 位算术之间的差异,因此可能不需要调整。

    【讨论】:

    • 很抱歉让您失望了,但是那里的参考在一个沼泽普通的 C++ for 循环中也使用了 32 位浮点数。我不知道 Trondeau 为什么会写这个(我怀疑他现在还记得),但据我所知,我们的 SSE、SSE2、SSE4.1/2 和 AVX 加速代码,dotproducts(这是正在测试的这里)对于“正常”浮点值(即,不是 NaN,不是 +- Inf,不是 -0)几乎相同。
    • 请注意,自 2012 年以来,我们向前迈进了一步:数学算法的加速(或幼稚)实现不再是 FIR 滤波器代码本身的一部分,而是从 @987654322 链接/编译@,内核向量优化库,它自己进行测试(我并不总是 100% 满意)。
    猜你喜欢
    • 2016-08-23
    • 2018-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-24
    • 2012-03-19
    • 2015-11-02
    相关资源
    最近更新 更多