MS Visual C ++は、SSE4.2を搭載したCPUで2種類のpopcnt命令をサポートしています。
私が見つけた唯一の違いは、のドキュメントが__popcnt()
「Microsoft固有」としてマークされ_mm_popcnt_u32()
ており、固有のコマンド名(MS固有ではない)のように見えることです。
これが唯一の違いであり、MS__popcnt()
はHWを呼び出すだけ_mm_popcnt_u32()
ですか?
MS Visual C ++は、SSE4.2を搭載したCPUで2種類のpopcnt命令をサポートしています。
私が見つけた唯一の違いは、のドキュメントが__popcnt()
「Microsoft固有」としてマークされ_mm_popcnt_u32()
ており、固有のコマンド名(MS固有ではない)のように見えることです。
これが唯一の違いであり、MS__popcnt()
はHWを呼び出すだけ_mm_popcnt_u32()
ですか?
Intel と AMD のおかげで、これらは同じ機械語命令の 2 つの異なる組み込み名です。 命令は、それをサポートするすべての CPU で同じであり、異なる組み込み関数も C または C++ で違いはありません。
__popcnt*() ビルトインは、AMD の Advanced Bit Manipulation (ABM) 命令用です。http://blogs.amd.com/developer/2007/09/26/barcelona-processor-feature-advanced-bit-manipulation-abm/を参照してください。
_mm_popcnt_u*() 組み込み関数は Intel の実装用であり、SSE4.2 自体の一部ではありませんが、ほぼ同時に実装されました。http://en.wikipedia.org/wiki/SSE4#POPCNT_and_LZCNTを参照
https://www.chessprogramming.org/Population_Countによると、固有の名前が異なるにもかかわらず、両方の実装はバイナリ互換です。
Intel のアーキテクチャ マニュアルには、次のように記載されています。
アプリケーションが POPCNT 命令を使用しようとする前に、プロセッサが SSE4.2 (CPUID.01H:ECX.SSE4_2[bit 20] = 1 の場合) および POPCNT (CPUID.01H:ECX.POPCNT[bit 23 の場合) をサポートしていることを確認する必要があります。 ] = 1)。
AMD のAMD64 Architecture Programmer's Manual Volume 3: General Purpose and System Instructions によると
POPCNT 命令のサポートは、CPUID 関数 0000_0001h によって返される ECX ビット 23 (POPCNT) によって示されます。ソフトウェアは、POPCNT 命令を使用する前に、プログラムまたはライブラリの初期化ごとに CPUID ビットをチェックする必要があります。そうしないと、一貫性のない動作が発生する可能性があります。
popcnt が SSE4.2 の存在を必要とする理由が見当たらないので、popcnt の存在を判断するには ECX のビット 23 をチェックするだけで十分だと思います。
popcnt を備えた最初の AMD CPU である AMD の Barcelona は、SSE4 を完全には実装していませんでした。そのため、Intel のアーキテクチャ マニュアルが、Intel CPU で機能し、認定された AMD CPU でも失敗する存在を判断する方法を提案している可能性があります。
Intel のvol.2 命令セット リファレンス マニュアルの現在のドキュメントでpopcnt
#UD If CPUID.01H:ECX.POPCNT [Bit 23] = 0
popcnt
は、 SSE4.2 を使用しない一部の AMD CPUでソフトウェアが利用されないことにつながる反競争的な提案はなくなっているとのみ述べています。