インテル®64およびIA-32アーキテクチャー最適化リファレンス・マニュアル§5.1は、整数/ FPの「データ型」の混合について同様のことを述べています(ただし、不思議なことに、シングルとダブルではありません)。
整数データと浮動小数点データの両方で機能するSIMDコードを作成する場合は、SIMD変換命令またはロード/ストア命令のサブセットを使用して、XMMレジスタの入力オペランドに命令と一致するように適切に定義されたデータタイプが含まれるようにします。
クロスタイプの使用法を含むコードシーケンスは、異なる実装間で同じ結果を生成しますが、パフォーマンスが大幅に低下します。SSE / SSE2 / SSE3 / SSSE3 / SSE44.1命令を使用して、XMMレジスタのタイプが一致しないSIMDデータを操作することは強くお勧めしません。
インテル®64およびIA-32アーキテクチャーソフトウェア開発者マニュアルは、同様に混乱を招きます。
SSEおよびSSE2拡張機能は、パックドおよびスカラー浮動小数点データ型と128ビットSIMD整数データ型の型指定された操作を定義しますが、IA-32プロセッサはアーキテクチャレベルでこの型指定を強制しません。彼らはそれをマイクロアーキテクチャレベルでのみ実施します。
..。
Pentium4およびIntelXeonプロセッサは、無効オペランド例外(#UD)を生成せずにこれらの命令を実行し、レジスタXMM0で期待される結果を生成します(つまり、各レジスタの上位64ビットと下位64ビットは倍精度として扱われます。精度の浮動小数点値とプロセッサはそれに応じて動作します)。
..。
この例では、XORPDの代わりにXORPSまたはPXORを使用して、同じ正しい結果を得ることができます。ただし、オペランドデータ型と命令データ型の型が一致しないため、マイクロアーキテクチャレベルでの命令の実装によりレイテンシペナルティが発生します。
間違ったタイプの移動命令を使用することによっても、レイテンシーペナルティが発生する可能性があります。たとえば、MOVAPSとMOVAPDの両方を使用して、パックされた単精度オペランドをメモリからXMMレジスタに移動できます。ただし、MOVAPDを使用すると、正しく入力された命令がレジスタ内のデータを使用しようとすると、レイテンシペナルティが発生します。
XMMレジスタからメモリにデータを移動する場合、これらのレイテンシペナルティは発生しないことに注意してください。
さまざまな「データ型」がμarchによって異なる方法で処理されることを示唆していることを除いて、「マイクロアーキテクチャレベルでのみ強制する」とはどういう意味か本当にわかりません。私はいくつかの推測があります:
- AIUI、x86コアは通常、レジスタが不足しているため、レジスタの名前変更を使用します。おそらく、整数/シングル/ダブルオペランドに異なるレジスタを内部的に使用しているため、それぞれのベクトル単位の近くに配置できます。
- また、FP番号が内部で異なる形式を使用して表され(たとえば、より大きな指数を使用してデノルムを取り除く)、必要な場合にのみ正規ビットに変換される可能性もあります。
- CPUは「転送」または「バイパス」を使用するため、実行ユニットは、データがレジスタに書き込まれるのを待ってから後続の命令で使用できるようになり、通常は1〜2サイクル節約できます。これは、整数ユニットとFPユニットの間では発生しない可能性があります。