私はx86命令セットの拡張機能について読んでいますが、それらは非常に特殊な状況でのみ役立つようです(たとえば、SSE3のHADDPD-(Horizontal-Add-Packed-Double))。これらには、意図的に設定するか、その前の一連の命令から発生する必要がある特定のレジスタレイアウトが必要です。gccのような汎用コンパイラは実際にこれらの命令(またはそのサブセット)を使用する頻度はどれくらいですか、それとも主に手動でコーディングされたアセンブラで使用されますか?コンパイラは、SIMD命令を使用するのが適切な場所をどのように検出しますか?
5 に答える
一般的に、それらを使用するコンパイラはほとんどありません。GCCとVisualStudioは通常、SIMD命令を使用できません。SSEをコンパイラフラグとして有効にすると、通常の浮動小数点演算にスカラーSSE命令が使用されますが、通常、ベクトル化されたものが自動的に使用されることは期待できません。GCCの最近のバージョンでは、場合によってはそれらを使用できる可能性がありますが、最後に試したところ、機能しませんでした。IntelのC++コンパイラは、いくつかのループを自動ベクトル化できることを私が知っている唯一の大きなコンパイラです。
ただし、一般的には、自分で使用する必要があります。rawアセンブラで、またはコンパイラ組み込み関数を使用して。一般に、組み込み関数の方が優れたアプローチだと思います。コンパイラーがコードを理解し、スケジュールを設定して最適化できるためですが、実際には、MSVCは少なくとも組み込み関数から非常に効率的なコードを生成するとは限りません。プレーンなasmが最良の解決策かもしれません。実験して、何が機能するかを見てください。ただし、1)適切なコンパイラを使用し、2)簡単にベクトル化できる非常に単純なループを作成しない限り、コンパイラがこれらの命令を使用することを期待しないでください。
2012年の更新
わかりました。この回答を書いてから3年が経過しました。GCCはここ数年(単純な)コードを自動ベクトル化することができ、VS2012ではMSVCがついに同じ機能を獲得しました。もちろん、私の答えの主要部分はまだ当てはまります。コンパイラーは、かなり些細なコードしかベクトル化できません。もっと複雑なことについては、組み込み関数やインラインasmをいじくりまわしていることになります。
モノラルは、そのクラスをベクトルに使用する限り、SIMD拡張機能を使用できます。あなたはここでそれについて読むことができます:http://tirania.org/blog/archive/2008/Nov-03.html
-O3GCCは、特定のフラグを使用している限り、自動ベクトル化を実行する必要があります。ここに情報ページがあります:http://gcc.gnu.org/projects/tree-ssa/vectorization.html
SSEやその他の小さなベクトル単位を自動的に活用する方法(特別な言語構造や特別に祝福されたコンパイラー「組み込み関数」の形でプログラマーからの指示なしに)の問題は、しばらくの間コンパイラー研究のトピックでした。ほとんどの結果は、デジタル信号処理などの特定の問題領域に特化しているようです。私はこのトピックに関する文献に追いついていないが、私が読んだことは、ベクトル(SSE)ユニットの活用はまだ研究のトピックであり、この分野で一般的に使用される汎用コンパイラーへの期待は低いはずであることを示唆している。
推奨される検索用語:ベクトル化コンパイラ
gccがsseを使用してデフォルトのstd::stringオブジェクトをゼロにするのを見てきました。sseの特に強力な使用法ではありませんが、存在します。ほとんどの場合、あなたはあなた自身を書かなければならないでしょうが。
スタックが整列しなくなり、クラッシュしたため、これを知っています。そうでなければ、おそらく気付かなかったでしょう。
ベクターパスカルコンパイラを使用すると、SIMDが有利なタイプの効率的なSIMDコードを取得できます。基本的に、これは64ビット未満の長さのものです。(64ビット実数の場合、SIMDを実行するのは実際には遅くなります)。最新バージョンのコンパイラは、コア間で自動的に並列化されます