从SIMD指令捕获SIGFPE

时间:2016-09-25 18:16:09

标签: c signals simd

我正在尝试清除浮点除以零标志以忽略该异常。我期待着设置了标志(我认为默认行为没有变化,并在下面注释掉),我的错误处理程序将触发。但是,_mm_div_ss似乎没有提高SIGFPE。有什么想法吗?

#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <xmmintrin.h>

static void sigaction_sfpe(int signal, siginfo_t *si, void *arg)
{
    printf("inside SIGFPE handler\nexit now.");
    exit(1);
}

int main()
{
    struct sigaction sa;

    memset(&sa, 0, sizeof(sa));
    sigemptyset(&sa.sa_mask);
    sa.sa_sigaction = sigaction_sfpe;
    sa.sa_flags = SA_SIGINFO;
    sigaction(SIGFPE, &sa, NULL);

    //_mm_setcsr(0x00001D80); // catch all FPE except divide by zero

    __m128 s1, s2;
    s1 = _mm_set_ps(1.0, 1.0, 1.0, 1.0);
    s2 = _mm_set_ps(0.0, 0.0, 0.0, 0.0);
    _mm_div_ss(s1, s2);

    printf("done (no error).\n");

    return 0;
}

以上代码的输出:

$ gcc a.c
$ ./a.out 
done (no error).

如您所见,我的处理程序永远不会到达。旁注:我已经尝试了几种不同的编译器标志(-msse3,-march = native),没有任何变化。

gcc(Debian 5.3.1-7)5.3.1 20160121

/ proc / cpuinfo

中的一些信息
model name      : Intel(R) Core(TM) i3 CPU       M 380  @ 2.53GHz
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 popcnt lahf_lm arat dtherm tpr_shadow vnmi flexpriority ept vpid

1 个答案:

答案 0 :(得分:1)

两件事。

首先,我误解了文档。例外情况需要 unmasked 才能被捕获。调用_mm_setcsr(0x00001D80);将允许SIGFPE在除以零时触发。

其次,即使使用-O0,gcc也在优化我的除法指令。

给定源线

_mm_div_ss(s1, s2);

使用gcc -S -O0 -msse2 a.c进行编译

76     movaps  -24(%ebp), %xmm0
77     movaps  %xmm0, -72(%ebp)
78     movaps  -40(%ebp), %xmm0
79     movaps  %xmm0, -88(%ebp)

a1     subl    $12, %esp        ; renumbered to show insertion below
a2     pushl   $.LC2
a3     call    puts
a4     addl    $16, %esp

源线

s2 = _mm_div_ss(s1, s2); // add "s2 = "

给出

76     movaps  -24(%ebp), %xmm0
77     movaps  %xmm0, -72(%ebp)
78     movaps  -40(%ebp), %xmm0
79     movaps  %xmm0, -88(%ebp)
       movaps  -72(%ebp), %xmm0
       divss   -88(%ebp), %xmm0
       movaps  %xmm0, -40(%ebp)
a1     subl    $12, %esp
a2     pushl   $.LC2
a3     call    puts
a4     addl    $16, %esp

通过这些更改,将根据MXCSR中的被零除标志调用SIGFPE处理程序。