2016-09-25 6 views
1

浮動小数点除算フラグをクリアしてその例外を無視しようとしています。私はフラグが設定されている(私は信じて、デフォルトの動作からの変更はありません)、下にコメントアウトを期待している、私のエラーハンドラが発生します。しかし、_mm_div_ssはSIGFPEを上げていないようです。何か案は?上記のコードからSIMD命令から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

MXCSRで関連する例外をマスク解除する必要があると思います。すべてのFP例外はデフォルトでマスクされます。私はFP例外からシグナルを生成するプログラムを書こうとしていませんでしたが、その定数が正しい場合には '_mm_setcsr'が動作すると推測しました。テストのために、POSIXの要求に応じて、実際にx86 Linux上でSIGFPEをゼロで除算してトリガすることができます。 (http://stackoverflow.com/questions/37262572/on-which-platforms-does-integer-divide-by-zero-trigger-a-floating-point-exceptio) –

+0

'_mm_setcsr(0x00001F80) 'でも何も起こりません。 SIGFPEをゼロで除算してSIGFPEをテストできるのは間違いありませんが、MXCSRにそれが起こるかどうかを制御しようとしています。 – BurnsBA

+0

私のコメントは編集できませんが、 '_mm_setcsr(0x00000000)'は同じ効果をもたらします(シグナルは発生しません)。 – BurnsBA

答えて

1

2つのこと。

まず、私はドキュメントを誤解しました。例外は、マスクされていないをキャッチする必要があります。 _mm_setcsr(0x00001D80);を呼び出すと、SIGFPEはゼロで除算されます。

第2に、gccは-O0でも除算命令を最適化していました。ソースライン

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 
を与えながら

考えるとソースラインgcc -S -O0 -msse2 a.cしてコンパイル

_mm_div_ss(s1, s2); 

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 

を与えます

これらの変更により、MXCSRのゼロ除算フラグに従ってSIGFPEハンドラが呼び出されます。

関連する問題