什么可能导致确定性过程生成浮点错误 [英] What could cause a deterministic process to generate floating point errors

查看:248
本文介绍了什么可能导致确定性过程生成浮点错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

已阅读此问题我可以肯定,给定的使用具有相同输入(在相同硬件上,用相同编译器编译)的浮点算术的过程应该是确定性的。我正在看一个这样的情况,这不是真的,并试图确定是什么可能造成这种情况。



我编译了一个可执行文件,我喂它完全相同的数据,运行在单个机器(非多线程),但我得到的大约3.814697265625e-06的错误,仔细googling后,我发现实际上等于1/4 ^ 9 = 1/2 ^ 18 = 1 / 262144。这非常接近32位浮点数的精度水平(根据维基百科大约7位数)



我的怀疑是,它与优化有关已经应用于代码。我使用intel C ++编译器,并已将浮点推测快,而不是安全或严格。这可能使浮点过程是非确定性的吗?有没有其他优化等可能导致这种行为?



编辑:根据Pax的建议,我重新编译代码与浮点投机转向安全,我现在得到稳定的结果。这允许我澄清这个问题 - 什么是浮点推测实际上做什么和如何可以导致相同的二进制(即一个编译,多个运行)生成不同的结果,当应用于完全相同的输入?



@我用英特尔(R)C ++ 11.0.061 [IA-32]编译,我在英特尔四核处理器上运行。

解决方案

在几乎任何情况下,有一个快速模式和安全模式,你会发现某种。否则一切都将以快速安全模式运行: - )。



如果你用同样的输入得到不同的结果,你的过程是确定性,无论你相信它是多少(尽管有经验证据)。



我会说你的解释是最可能的。把它放在安全模式,看看非确定性是否消失。



至于是否有其他优化,如果你在同一个硬件上使用相同的编译器/链接器来编译相同的选项到这些工具,它应该生成相同的代码。我不能看到任何其他可能性,除了快速模式(或由于宇宙射线,在内存中的位腐烂,但是这是不太可能的)。



关注您的更新:



Intel有一个文档这里,说明他们在安全模式下不允许做的一些事情,包括但不限于:




  • reassociation:(a + b)+ c-> a +(b + c)

  • 零折叠: x + 0 - x,x * 0 - > 0

  • 互逆乘法: a / b - > a *(1 / b)



虽然声明这些操作是编译时定义的,英特尔芯片相当聪明。他们可以重新排序指令以保持管道在多CPU设置中的完整性,所以除非代码特别禁止这种行为,否则事情可能在运行时(而不是编译时)改变以保持全速运行。 p>

这涉及到关于向量化的链接文档的第15页(简短地)。(问题:不同的结果在相同的数据上重新运行相同的二进制文件相同的处理器)。



我的建议是决定您是否需要原始grunt或结果的完全可重复性,然后根据此选择模式。


Having already read this question I'm reasonably certain that a given process using floating point arithmatic with the same input (on the same hardware, compiled with the same compiler) should be deterministic. I'm looking at a case where this isn't true and trying to determine what could have caused this.

I've compiled an executable and I'm feeding it the exact same data, running on a single machine (non-multithreaded) but I'm getting errors of about 3.814697265625e-06 which after careful googling I found is actually equal to 1/4^9 = 1/2^18 = 1/262144. which is pretty close to the precision level of a 32-bit floating point number (approx 7 digits according to wikipedia)

My suspicion is that it has something to do with optimisations that have been applied to the code. I'm using the intel C++ compiler and have turned floating point speculation to fast instead of safe or strict. Could this make a floating point process non-deterministic? Are there other optimisations etc that could lead to this behaviour?

EDIT: As per Pax's suggestion I recompiled the code with floating point speculation turned to safe and I'm now getting stable results. This allows me to clarify this question - what does floating-point-speculation actually do and how can this cause the same binary (i.e. one compilation, multiple runs) to generate different results when applied to the exact same input?

@Ben I'm compiling using Intel(R) C++ 11.0.061 [IA-32] and I'm running on an Intel quadcore processor.

解决方案

In almost any situation where there's a fast mode and a safe mode, you'll find a trade-off of some sort. Otherwise everything would run in fast-safe mode :-).

And, if you're getting different results with the same input, your process is not deterministic, no matter how much you believe it to be (in spite of the empirical evidence).

I would say your explanation is the most likely. Put it in safe mode and see if the non-determinism goes away. That will tell you for sure.

As to whether there are other optimizations, if you're compiling on the same hardware with the same compiler/linker and the same options to those tools, it should generate identical code. I can't see any other possibility other than the fast mode (or bit rot in the memory due to cosmic rays, but that's pretty unlikely).

Following your update:

Intel has a document here which explains some of the things they're not allowed to do in safe mode, including but not limited to:

  • reassociation: (a+b)+c -> a+(b+c).
  • zero folding: x + 0 -> x, x * 0 -> 0.
  • reciprocal multiply: a/b -> a*(1/b).

While you state that these operations are compile-time defined, the Intel chips are pretty darned clever. They can re-order instructions to keep pipelines full in multi-CPU set-ups so, unless the code specifically prohibits such behavior, things may change at run-time (not compile-time) to keep things going at full speed.

This is covered (briefly) on page 15 of that linked document that talks about vectorization ("Issue: different results re-running the same binary on the same data on the same processor").

My advice would be to decide whether you need raw grunt or total reproducability of results and then choose the mode based on that.

这篇关于什么可能导致确定性过程生成浮点错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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