変数 shift op またはブランチを実際に使用せずに、間接的な左/右シフト操作を実行する方法を見つけようとしています。
私が取り組んでいる特定の PowerPC プロセッサには、次のような定数による即時シフトという癖があります。
int ShiftByConstant( int x ) { return x << 3 ; }
高速、単一操作、スーパースカラーであるのに対し、変数によるシフトは次のように
int ShiftByVar( int x, int y ) { return x << y ; }
はマイクロコード化された操作で、実行に 7 ~ 11 サイクルかかり、残りのパイプライン全体が完全に停止します。
私がやりたいのは、sraw がデコードするマイクロコード化されていない整数 PPC ops を特定し、それらを個別に発行することです。これは、それ自体のレイテンシーには役立ちませんsraw
— 1 つのオペレーションが 6 つに置き換えられます — しかし、それらの 6 つのオペレーションの間に、一部の作業を他の実行ユニットに二重ディスパッチして、純利益を得ることができます。
μops sraw がデコードしたものをどこにも見つけられないようです — 可変ビットシフトを一連の定数シフトと基本的な整数演算に置き換える方法を知っている人はいますか? (正しく予測された分岐であっても、分岐ペナルティはマイクロコード ペナルティよりもさらに大きいため、for ループ、スイッチ、または分岐を含むものは機能しません。)
これはアセンブリで答える必要はありません。私は特定のコードではなくアルゴリズムを学びたいと思っているので、C言語や高級言語、さらには疑似コードでの回答があれば完全に役に立ちます。
編集:追加する必要があるいくつかの説明:
- 携帯性は少しも気になりません
PPC には条件付き移動があるため、分岐のない組み込み関数の存在を想定できます。
int isel(a, b, c) { return a >= 0 ? b : c; }
(同じことを行う三項を書き出すと、あなたの言いたいことがわかります)
- 整数乗算もマイクロコード化されており、
sraw
. :-( - Xenon PPC では、予測される分岐のレイテンシは 8 サイクルであるため、1 つでもマイクロコード化された命令と同じくらいコストがかかります。ポインターへのジャンプ (任意の間接分岐または関数ポインター) は、予測ミス (24 サイクルのストール) が保証されています。