別の SSE 実装をスカラー コードに手作業でコーディングするのではなく、OpenCLを確認することを強くお勧めします。これは、計算量の多いアプリケーション向けの、ベンダーに依存しないポータブルなクロスプラットフォーム システムです (そして、バズワードに高度に準拠しています!)。ベクトル化された操作用に設計された C99 のサブセットでアルゴリズムを記述できます。これは、SSE を手作業でコーディングするよりもはるかに簡単です。そして何よりも、OpenCL は実行時に最適な実装を生成し、GPUまたはCPU で実行します。したがって、基本的には、SSE コードが作成されます。
私のコード ベースには、大規模なデータ セットに対して同じ操作が非常に多く繰り返される場所がいくつかあります。場合によっては、これらの処理にかなりの時間がかかります。
あなたのアプリケーションは、まさに OpenCL が対処するように設計された種類の問題のように思えます。SSE で代替関数を作成すると、確かに実行速度が向上しますが、作成とデバッグには多大な労力がかかります。
SSE命令を利用するためにコードを書くコンパイラとOSに依存しない方法はありますか? SSE 操作を含む VC++ 組み込み関数が気に入っていますが、クロス コンパイラ ソリューションは見つかりませんでした。
はい。SSE 組み込み関数は基本的に Intel によって標準化されているため、Windows、Linux、および Mac (特に Visual C++ と GNU g++) の間で同じ関数が同じように機能します。
SSE サポートがない、または制限されている一部の CPU (Intel Celeron など) をサポートする必要があります。プロセスの開始時に実行されている CPU に基づいて、基本コードまたは SSE 最適化コードのいずれかにリンクするある種の「実行時リンカー」を使用するなど、プログラムの異なるバージョンを作成する必要を回避する方法はありますか?
それを行うこともできますが (例: を使用dlopen()
)、これは非常に複雑なソリューションです。(C で) 関数インターフェイスを定義し、関数ポインターを介して最適化された関数の適切なバージョンを呼び出すか、C++ で検出された CPU に応じて異なる実装クラスを使用する方がはるかに簡単です。
OpenCL では、特定のアーキテクチャの実行時にコードが生成されるため、これを行う必要はありません。
他の CPU 拡張機能についてはどうですか。さまざまな Intel および AMD CPU の命令セットを見ると、それらのいくつかが示されていますか?
SSE 命令セットには、さまざまな種類があります。特定の命令が存在しない場合、SSE の異なるサブセットで同じアルゴリズムをコーディングすることは非常に困難です。(少なくとも最初は) SSE2 などのサポートされている最小レベルを選択し、古いマシンではスカラー実装にフォールバックすることをお勧めします。
これは、ユニット/回帰テストの理想的な状況でもあり、さまざまな実装で同じ結果が得られるようにするために非常に重要です。入力データと既知の適切な出力データのテスト スイートを用意し、両方のバージョンの処理関数で同じデータを実行します。合格するには、精度テストが必要になる場合があります (つまり、結果と正解の差のイプシロンは、1e6
たとえば以下のようになります)。これはデバッグに非常に役立ちます。テスト フレームワークに高解像度のタイミングを組み込むと、同時にパフォーマンスの向上を比較できます。