次の機能は1クロックサイクルで実行されますか?
__builtin_popcount
__builtin_ctz
__builtin_clz
また、同じのll(64ビット)バージョンのクロックサイクル数はいくつですか。それらはポータブルですか。なぜまたはなぜそうではないのですか?
これらの機能は単一のクロックサイクルで実行されますか?
必ずしも。単一の命令で実装できるアーキテクチャでは、通常、その関数を計算するための最速の方法になります(ただし、必ずしも単一のクロックサイクルである必要はありません)。単一の命令として実装できないアーキテクチャでは、パフォーマンスはそれほど確実ではありません。
私のプロセッサ(Core 2 Duo)では、単一の命令(BitScanForwardおよびBitScanReverse)で実装できます__builtin_ctz
。__builtin_clz
ただし、__builtin_popcount
プロセッサで1つの命令を使用して実装することはできません。の場合__builtin_popcount
、gcc 4.7.2はライブラリ関数を呼び出し、clang 3.1はインライン命令シーケンスを生成します(このビットをいじるハックを実装します)。明らかに、これら2つの実装のパフォーマンスは同じではありません。
それらはポータブルですか?
それらはコンパイラ間で移植可能ではありません。それらは(私が知る限り)GCCで作成され、Clangなどの他のコンパイラーでも実装されています。
これらの機能をサポートするコンパイラーは、複数のアーキテクチャーにそれらを提供する場合がありますが、実装の品質(パフォーマンス)は異なる可能性があります。
__builtin
このような関数は、インラインアセンブリを使用するよりもいくらか簡単な方法で特定のマシン命令にアクセスするために使用されます。最高のパフォーマンスを達成する必要があり、そのために移植性を犠牲にするか、これらの関数が提供されていないコンパイラまたはプラットフォームに代替実装を提供する場合は、それらを使用するのが理にかなっています。最適な低レベルのパフォーマンスが目標である場合は、コンパイラのアセンブリ出力もチェックして、使用する予定の命令が実際に生成されているかどうかを判断する必要があります。
-O3 -march=native -S
コンパイラをアセンブラコードにコンパイルすることで、コンパイラがそれをどのように処理するかを最初に知ることができます。そこで、これが1つのアセンブラステートメントだけに解決されるかどうかを確認できます。もしそうなら、これはこれが1サイクルで行われることを保証するものではありません。実際のコストを知るには、測定する必要があります。