2016-09-25 72 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'會起作用。對於測試,您可以實際觸發x86 Linux上的SIGFPE,除了POSIX所要求的整數除以零。 (http://stackoverflow.com/questions/37262572/on-which-platforms-does-integer-divide-by-zero-trigger-a-floating-point-exceptio) –

+0

即使有'_mm_setcsr(0x00001F80)'什麼也沒有發生。你是對的,我可以測試整數除零的SIGFPE,但我試圖讓MXCSR來控制是否發生這種情況。 – BurnsBA

+0

無法編輯我的評論,但'_mm_setcsr(0x00000000)'具有相同的效果(未引發任何信號)。 – BurnsBA

回答

1

兩件事情。

首先,我誤解了文檔。例外情況需要被捕獲未被掩蓋的。調用_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 

通過這些更改,SIGFPE處理程序根據MXCSR中的除零標誌被調用。