2011-07-16 15 views
6

OpenMPをいくつかのSSEコードに追加しようとしています。OpenMpとSSEを使用したセグメンテーションフォルト

私の最初のテストプログラムSOMETIMESは_mm_set_psでクラッシュしますが、if(0)を設定すると動作します。

とてもシンプルに見えますが、私は明らかなものを紛失しているはずです。私はgccでコンパイルしてい -fopenmp -g -march = Core2のは

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

    int main() 
    { 
    #pragma omp parallel if (1) 
    { 
    #pragma omp sections 
     { 
    #pragma omp section 
      { 
       __m128 x1 = _mm_set_ps (1.1f, 2.1f, 3.1f, 4.1f); 
      } 
    #pragma omp section 
      { 
       __m128 x2 = _mm_set_ps (1.2f, 2.2f, 3.2f, 4.2f); 
      } 
     } // end omp sections 
    } //end omp parallel 

    return 0; 
    } 

答えて

6

これはopenMP実装のバグです。私はgccのWindows(MinGW)で同じ問題を抱えていました。 -mstackrealignコマンドラインオプションが私の問題を解決しました。これにより、すべての関数のプロローグに命令が追加され、16バイト境界でスタックを再配置します。パフォーマンスのペナルティは気付かなかった。 __attribute__ ((force_align_arg_pointer))を関数宣言に追加することもできます。これは同じことを行う必要がありますが、特定の関数に対してのみ行う必要があります。 #pragma ompを使って関数から呼び出す別の関数にSSEコードを入れなければならないかもしれないので、スタックは再配置される可能性があります。

64ビットターゲット(MinGW64、TDM GCCビルドなど)のコンパイルに移動したときに、この問題が発生しなくなりました。

私は32バイトのアライメントを必要とするAVX命令で再生していますが、GCCはそれをまったくサポートしていません。これは、私がPythonスクリプトを使用して生成されたアセンブリコードを修正することを余儀なくされましたが、機能します。

+0

-mstackrealignを使用すると問題が解決されたようです。パフォーマンスペナルティがある場合でも、パフォーマンスよりも優れています。より複雑なコードをどのように使用するかを見ていきます。ご協力いただきありがとうございます。残念ながら、私は64ビットのマシンを持っていません。私はAVX pcを持っているので、gccがそれをまだサポートしていないことは残念です。 –

+0

正確に言えば、gccはCore i7 2nd gen(Sandy Bridge)を含むAVXをサポートしています。オンラインで読むと、Linux上でうまく動作します。しかし、私はMinGW64でWindows上で多くのセグメンテーション障害の問題を抱えていたので、おそらくMinGW関連のバグでしょう。しかし、私はちょうど何か間違っているかもしれません... –

+0

g ++のオプション '-mstackrealign'は完全に働きました。代わりに、私の場合、関数呼び出しが最初にあったことを確認するために 'noinline'属性を追加しなければなりません:' __attribute __((force_align_arg_pointer、noinline)) ' – phfaist

2

私は非整列メモリアクセスをかぐ-pthreads。そのような唯一のコードは、爆発する可能性があります(です)。それが起こるためには、XMMレジスタは使用されず、スタックメモリは4バイトにしか整列しません。私の推測では、ompコードはスタックの位置合わせを乱してしまいます。

関連する問題