問題タブ [branch-prediction]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
gcc - Intel x86 0x2E/0x3E プレフィックス分岐予測は実際に使用されましたか?
最新の Intel ソフトウェア開発マニュアルでは、次の 2 つのオペコード プレフィックスについて説明しています。
これらにより、Jump 命令 (のようなオペコードJxx
)の明示的な分岐予測が可能になります。
数年前に、x86 での明示的な分岐予測は、gccs の分岐予測組み込み関数のコンテキストでは基本的にノーオペレーションだったという記事を読んだことを覚えています。
これらの x86 ブランチ ヒントが新しい機能なのか、それとも実際には基本的にノーオペレーションなのかは不明です。
誰でもこれをクリアできますか?
(つまり、gccs 分岐予測関数はこれらの x86 分岐ヒントを生成しますか? - そして、現在の Intel CPU はそれらを無視しませんか? - そして、いつこれが起こりましたか?)
アップデート:
簡単なテスト プログラムを作成しました。
以下に分解します。
2E や 3E が見えないのですが?何らかの理由で gcc がそれらを除外したのではないでしょうか?
c++ - 任意のソートされたデータに対して (ほとんど) 分岐のないバイナリ検索を実行するにはどうすればよいですか?
できれば移植可能な方法で、任意のソートされた配列で (ほとんど) ブランチのないバイナリ検索を実行するにはどうすればよいですか? (たとえば、コンパイラが CMOV 命令を生成するのを助けるコードは、これに最適です。)
「ほぼ」とは、「できるだけ少ないブランチを含む」ことを意味します。
x86 - Intel Last Branch Record を使用した場合のオーバーヘッドはどのくらいですか?
最後の分岐レコードは、最近実行された分岐に関連するソース アドレスと宛先アドレスを格納するレジスタ ペア (MSR) のコレクションを指します。興味がある場合は、http://css.csail.mit.edu/6.858/2012/readings/ia32/ia32-3b.pdfドキュメントに詳細情報があります。
- a) CPU と IO の両方を集中的に使用する一般的なプログラムの実行速度が LBR によってどの程度低下するかを誰かが教えてくれますか?
- b) LBR トレースがオンの場合、分岐予測はオフになりますか?
c - GCCの__builtin_expect()をCの三項演算子で使用できますか?
GCCマニュアルには、「if」ステートメントの条件全体の周りに__builtin_expect()が配置されている例のみが示されています。
また、GCCは、たとえば、三項演算子を使用したり、分岐コンテキストで使用されていないものであっても、任意の整数式で使用しても文句を言わないことに気付きました。
それで、私はその使用法の根本的な制約が実際に何であるか疑問に思います。
次のような三項演算で使用した場合、その効果は保持されますか?
そして、この場合はどうですか?
そしてこれ:
assembly - 遅延スロットのポイントは何ですか?
そのため、遅延スロットに関する私の理解では、分岐命令が呼び出されたときに発生し、分岐に続く次の命令もメモリからロードされます。これのポイントは何ですか?分岐が行われた場合に、分岐後のコードが実行されないと思いませんか? ブランチが取られなかった場合に時間を節約するためですか?
私はパイプライン図を見ていますが、とにかく分岐後の命令が実行されているようです..
c++ - C++ 比較関数のマイクロ最適化
Compare()
次のような関数があります。
分岐を避けるために最適化することにしました。
次に、これを実行してテストしました:
結果:
私はケースクローズドと言います.FTWの分岐は避けてください. しかし、完全を期すために、私は置き換えました
と:
〜3.14nsのまったく同じ測定値を得ました。おそらく、その時点で分岐は行われておらず、コンパイラーは実際にステートメントCompare()
を回避するために書き直しています。if
しかし、なぜCompare2()
速いのでしょうか?
残念ながら、私はアセンブリ コードの知識がありません。そうでなければ、自分でこれに答えようとしたでしょう。
編集:以下はいくつかのアセンブリです:
現在、テストを実行する実際のコードは、上記の 2 つの関数のインライン バージョンを使用している可能性があるため、これが分析するコードとして間違っている可能性があります。jmp
そういえば にコマンドが見えますCompare()
ので、分岐しているということだと思います。もしそうなら、この質問は次のようになると思います:なぜ分岐予測子は、からにCompare()
変更したときのパフォーマンスを改善しないのですか?a[i]
rand()%2
true
false
EDIT2:投稿をより賢明にするために、「分岐予測」を「分岐」に置き換えました。
assembly - 先頭に「jmp 0f」または「b 0f」を含むインライン アセンブリ
更新しました
アセンブリの 2 行目を実際に使用されているニーモニック ( mflr
) に変更し、下部に詳細情報を追加しました。
次のようなコード (gcc を使用) に出くわしました (言い換え):
... ここで、b
命令 (ppc) は短い jmp でmflr
あり、「リンク レジスタ」の内容を取得しています。これは、いくつかの点でプログラム カウンターに似ています。Intelコードでもこの種のものを見てきました(この質問で受け入れられた回答を参照)。
ブランチはノーオペレーションとして機能します...私の質問:これはどのような目的に役立ちますか?
分岐予測と関係があると思いますが、これまでのところ、検索中にこのイディオムを使用している人々のコードしか見つかりませんでした。
分岐予測の推測が間違っていたようです。 mflr
リンクレジスタの内容を取得します。
つまり、私の質問は次のようになります。なぜブランチが必要なのかということです。
branch-prediction - 2 ビットの分岐予測はより高いパーセンテージを与えるはずです
私は、2 ビットの分岐予測子の成功した予測のパーセンテージを計算することになっている小さなプログラムを持っています。すべて完了しましたが、出力は期待したものではありません。パーカンテージは、98% または 99% である必要があると思われるものではなく、約 91% で停止します。問題は、アドレスにマスクを適用する方法にあると思います。誰かが私のコードを見て、それが問題かどうかを確認できますか?
プログラムは、約 1792 個のアドレスと、分岐が行われた場合は 1、分岐が行われなかった場合は 0 の 1 桁の列で構成される gcc コンパイラの実行の分岐履歴を持つファイルを反復処理します。
出力は次のとおりです。
c++ - 分岐せずに文字が等しいかどうかを比較する
この関数を最適化したかった前の質問:
s1i == s2[j] ? 0 : 1
ユーザーは、条件付き((s1i - s2[j]) & 0x80) >> 7
ジャンプを防ぐために に置き換えることができるとコメントしました。トリックが間違っていて、ユーザーはコメントを削除しましたが、実際にそれを行う方法があるかどうか疑問に思っています。