Inconsistent behaviour in identical code

前端 未结 3 952
刺人心
刺人心 2021-01-22 11:53

An error trap trips after running a physics simulation for about 20 minutes. Realising this would be a pain to debug, I duplicated the relevant subroutine in a new project, and

3条回答
  •  不要未来只要你来
    2021-01-22 12:22

    I can confirm the problematic output you’re getting can be caused by a change in x87 precision. The precision value is stored in x87 FPU control register, and when changed, the value persists through the lifetime of your thread, affecting all x87 code running on the thread.

    Apparently, some other component of your huge program (or an external library you use) sometimes changes mantissa length from 53 bits (which is the default) to 64 bits (which means use the full precision of these 80 bit x87 registers).

    The best way to fix, switch your compiler from x87 to SSE2 target. SSE always use either 32 or 64-bit floats (depending on the instructions used), it doesn’t have 80-bit registers at all. Even your 2003 Athlon 64 already supports that instruction set. As a side effect, your code will become somewhat faster.

    Update: If you don’t want to switch to SSE2, you can reset the precision to whatever value you like. Here’s how to do that in Visual C++:

    #include 
    uint32_t prev;
    _controlfp_s( &prev, _PC_53, _MCW_PC ); // or _PC_64 for 80-bit
    

    For GCC, it’s something like this (untested)

    #include 
    #define _FPU_PRECISION ( _FPU_SINGLE | _FPU_DOUBLE | _FPU_EXTENDED )
    fpu_control_t prev, curr;
    _FPU_GETCW( prev );
    curr = ( prev & ~_FPU_PRECISION ) | _FPU_DOUBLE; // or _FPU_EXTENDED for 80 bit
    _FPU_SETCW( curr );
    

提交回复
热议问题