2017-03-17 12 views
0

私は次のコードのための奇妙なエラーを取得しています:_mm_fmadd_pdプログラム受信信号SIGILL、不正な命令

#include <assert.h> 
#include <stdio.h> 
#include <immintrin.h> 

inline static double myfma(double x,double y, double z) { 
    double r; // result                                      
    __m128d xx, yy, zz,rr; 

    xx = _mm_set_sd(x);// xx[0]=x, xx[1]=undefined                               
    yy = _mm_set_sd(y);// yy[0]=y, yy[1]=undefined                               
    zz = _mm_set_sd(z);// zz[0]=z, zz[1]=undefined                               
    r = _mm_cvtsd_f64(_mm_fmadd_pd(xx,yy,zz)); 

    return r; 
} 

void testfma() { 
    double x, y, z, res; 
    x = 1.0; 
    y = 2.0; 
    z = 3.0; 

    res = myfma(x,y,z); 
    printf("test: res = x*y + z \n"); 
    printf(" x: %g\n", x); 
    printf(" y: %g\n", y); 
    printf(" z: %g\n", z); 
    assert(res == 5.0); 
} 


int main() { 
    testfma(); 
    return 0; 
} 

としてコードをコンパイル:

g++ test.cpp -o a.out -std=c++11 -mavx2 -mfma -march=native -g 

私が取得しています実行可能ファイルを実行するとメッセージ:

Illegal instruction (core dumped) 

詳細を取得するためにgdbを使用:

gdb ./a.out 
(gdb) r 
(gdb) r 
Starting program: .... 

Program received signal SIGILL, Illegal instruction. 
0x000000000040067d in _mm_fmadd_pd(double __vector(2), double __vector(2), double __vector(2)) (__C=..., __B=..., __A=...) 
    at /usr/lib/gcc/x86_64-linux-gnu/5/include/fmaintrin.h:42 
42             (__v2df)__C); 

次のようにvalgrindのを使用している場合しかし:

valgrind ./a.out 
==9825== Memcheck, a memory error detector 
==9825== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. 
==9825== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright 

info 
==9825== Command: ./helios.x 
==9825== 
test: res = x*y + z 
    x: 1 
    y: 2 
    z: 3 
    res: 5 
==9825== 
==9825== HEAP SUMMARY: 
==9825==  in use at exit: 0 bytes in 0 blocks 
==9825== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated 
==9825== 
==9825== All heap blocks were freed -- no leaks are possible 
==9825== 
==9825== For counts of detected and suppressed errors, rerun with: -v 
==9825== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 

プログラムが動作しているようです。私はここで何が欠けているのですか? _mm_fmadd_pdを堅牢な方法で使用するにはどうすればよいですか?インテルまたはAMDプロセッサで動作しているかどうかにかかわらず、このサンプルを動作させることは可能ですか? g ++やicpcを使ってコンパイルすることは可能ですか?

+0

あなたのCPUにFMAがありますか?また、 '-g'でコンパイルして、gdbがクラッシュしたときに何が起きているのかを確認することができます。 –

+0

-gフラグを使用すると、エラーが発生します: (gdb)r 開始プログラム:.... .. プログラム受信信号SIGILL、不正な命令。 0x000000000040067d in _mm_fmadd_pd(ダブル__vector(2)、ダブル__vector(2)、ダブル__vector(2))(__C = ...、__ B = ...、__A = ...) /usr/lib/gcc /x86_64-linux-gnu/5/include/fmaintrin.h:42 42(__v2df)__ C); –

答えて

0

あなたのCPUはFMA命令をサポートしていないと思います。 valgrindが特定の指示をエミュレートすることができるため、valgrindで失敗しない理由があります。

SISDだけが必要な場合は、std::fmaを使用することをおすすめします。 With gcc it generates an inline FMA instructionですが、FMA以外のターゲット用にコンパイルした場合はfall back to a non-FMA implementationとなります。

関連する問題