【问题标题】:Perfectly fine division throws floating point exception完美的除法引发浮点异常
【发布时间】:2018-12-30 23:56:06
【问题描述】:

我有一个神秘的浮点异常。 我通过这样做来抓住它:

feenableexcept( FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW );

然后是这段代码中的第二个除法(最后一行):

const float dx = other.px[ j ] - curx;    
const float dy = other.py[ j ] - cury;
const float dsqr = dx*dx + dy*dy;
ASSERTM( dsqr > 0.0f, "dx %f dy %f dsqr %f", dx, dy, dsqr ); 
const float dist = sqrtf( dsqr );                   
ASSERTM( dist > 0.0f, "dx %f dy %f dsqr %f dist %f", dx, dy, dsqr, dist );
LOGI( "dx %f dy %f dsqr %f dist %f", dx, dy, dsqr, dist );
const float dirx = dx / dist;      
const float diry = dy / dist;

如下抛出一个 SIGFPE:

除数(在控制台打印,也由 gdb 打印)是 1.0839119,分子是 -1.05979919,所以我看不出有什么问题。

对于额外的怪异:

  • 在 -O0 调试版本中不会发生。
  • 如果我通过 valgrind 运行应用程序则不会发生

编译器:

$ clang -v
clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)

以及编译器选项:

clang++ -DXWIN -DLANDSCAPE -DUSECOREPROFILE -Dlinux -D_POSIX_C_SOURCE=199309L -D_DEFAULT_SOURCE -DAPPVER=1.00 -DLOGTAG=minimal -I/home/bram/src/stb/ -I/home/bram/include -I/public -I/home/bram/src/dutch-blunt/src -I/home/bram/apps/GBase/src -IPI -I/home/bram/src/ThreadTracer `/home/bram/bin/sdl2-config --cflags` -g -Wall -Wshadow -Wno-conversion -Wno-missing-braces -Wno-old-style-cast -Wno-unknown-pragmas -MMD -MP -O2 -std=c++11   -c -o PI/stars.o PI/stars.cpp

为什么会发生这种 FPE?我能想到的唯一原因是,即使它是一个标量除法,clang 也会生成一个 SIMD 除法。如果 XMM 寄存器中的其他通道包含零分母怎么办?如果任何通道被零除,SIMD 划分是否会生成 FPE?如果是这样,我怎么能捕获 FPE?

【问题讨论】:

  • 布拉姆,我会说你是对的,divps 文档说Performs a SIMD divide of the four, eight or sixteen packed single-precision floating-point values in the first source operand (the second operand) by the four, eight or sixteen packed single-precision floating-point values in the second source operand (the third operand). 这可能是编译器错误。
  • 我认为,如果要将 simd 用于两个分区,它将确保其他分区(强制分区)有效。也许他们从未在启用异常的情况下对其进行过测试。我建议在 clang bug 网站上提出这个问题,看看他们怎么说。
  • gccclang 基本上不支持非默认浮点环境。你可以试试-fsanitize=float-divide-by-zero

标签: floating-point clang x86-64 floating-point-exceptions


【解决方案1】:

clang version 10 compiler option 将确保未使用的通道不会导致 FP 异常:

-ffp-exception-behavior=maytrap

我已经对其进行了测试,它确实有效:它可以防止虚假的浮点异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-26
    • 1970-01-01
    • 2017-08-18
    • 1970-01-01
    • 1970-01-01
    • 2013-03-14
    • 1970-01-01
    相关资源
    最近更新 更多