1 ポイント 投稿者 GN⁺ 2024-12-02 | 1件のコメント | WhatsAppで共有
  • ASRock B650 PG Lightningの新しいBIOSでは、Zen 4のループバッファがもはやマイクロop供給元として観測されず、以前のBIOSに戻すと再び有効になる
  • この構造は、小さなループをフロントエンドで繰り返し処理して電力を削減する機能とみられ、単一スレッドでは144エントリ、SMT 2スレッド時にはスレッドあたり72エントリと推定される
  • SPEC CPU2017では、ループバッファ有効/無効間の総合スコア差は1%未満で、一般的な性能への影響は非常に小さいとみられる
  • ループバッファが無効になると、Zen 4はより多くのマイクロopをop cacheから供給し、op cache帯域幅はバックエンド処理量より十分大きいため、フロントエンドのボトルネックにはなりにくい
  • 無効化の理由と実際の電力影響は不明だが、AMDがほとんど文書化も宣伝もしていない限定的な機能であるため、大半のユーザーや開発者は変化を体感しにくい

Zen 4ループバッファの役割と限界

  • ループバッファはCPUフロントエンドで既にフェッチした少数の命令を保持し、小さなループを繰り返し実行する際にフロントエンドの一部段階を停止できるようにする構造
    • 省電力に役立つ可能性がある
    • フロントエンド側の制約を回避して性能を改善できる余地もある
    • Intel、Arm、AMDコアで古くから使われてきた手法
  • Zen 4は、高性能AMDコアの中でループバッファを備える唯一の事例とみられる
  • Zen 4のProcessor Programming Referenceは、ループバッファをop cache、デコーダと並ぶマイクロop dispatch元として挙げている
  • 性能カウンタ実験から容量は次のように推定される
    • 単一スレッド実行時は144エントリ
    • SMT 2スレッド有効時はスレッドごとに72エントリへ静的分割
  • ループ内にCALL/RETがあると、Zen 4ループバッファはそのループをキャプチャできない
  • AMDのZen 4最適化ガイドはループバッファに触れず、hot code regionをop cache容量内に収めるよう助言するだけである

BIOSアップデート後に消えたループバッファ

  • ASRock B650 PG LightningをBIOS 3.10へ更新した後、ハードウェア性能監視ではループバッファがマイクロopをdispatchしないことが示された
  • BIOS 1.21へ戻すと、ループバッファは再び有効になる
  • 無効化は、BIOS 1.21のAGESA 1.0.0.6とBIOS 3.10のAGESA 1.2.0.2aの間で起きたとみられる
  • AMDはこの変更を別途発表も宣伝もせず適用した
  • Hot Chips 2024でAMD社員と交わした補足的な議論によれば、ループバッファは主に電力最適化目的の機能だった

SPEC CPU2017で見えた小さな性能差

  • SPEC CPU2017整数・浮動小数点suiteの総合スコアは、ループバッファ有効/無効間で1%未満の差にとどまる
  • SMT性能向上もループバッファ無効化の影響を受けない
  • 性能影響が小さい理由は、Zen 4のop cacheが既にバックエンドのrename/allocate段階で消費できる量を上回る帯域幅を提供しているため
  • ループバッファが有効でも、性能カウンタ上ではマイクロopのごく一部しかループバッファから供給されていない
  • 個別benchmarkでも大きな損失は確認されていない
    • 523.xalanbmkでは命令ストリームのうち無視できない割合をループバッファが担っていたが、スコアは新BIOSで9.48、旧BIOSで9.44と誤差範囲内
    • 544.nabではマイクロopのほぼ4分の1をループバッファから供給していたが、ループバッファを無効化した新BIOSでスコアは11.7となり、以前の11.5より1.7%上昇した
    • この上昇はrun-to-run varianceの可能性がある
  • 新BIOSの性能カウンタでは、op cacheがループバッファの役割を引き継ぎ、命令ストリームのより大きな割合を処理している
  • 507.cactuBSSNではop cache coverageがやや低下し、デコーダが全マイクロopの約4分の1を供給するパターンが見られる
    • 性能カウンタは100%正確な測定というより、全体的な傾向を示す道具である
    • フロントエンドdispatchはspeculative eventなので、誤予測分岐後に誤ってフェッチされた命令にも影響されうる

省電力の可能性とフロントエンド活動

  • ループバッファの主目的は性能向上ではなく、op cacheを含むフロントエンドのかなりの部分を機会的に停止することにある
  • Zen 4の性能監視機能にはcount maskがあり、イベントカウントが閾値を超えたサイクル数を数えられる
    • 閾値を1にすると、各マイクロop供給元が実際にマイクロopを供給したサイクル数を推定できる
    • これにより、ループバッファ有効時にフロントエンドをどれほど頻繁に停止できるかを見積もれる
  • SPEC CPU2017では、各供給元が有効だった頻度は、その供給元が渡したマイクロop比率と概ねよく一致する
  • 一部workloadでは、フロントエンドが何も供給しないサイクルもかなり多い
    • 502.gcc520.omnetppはバックエンドのメモリレイテンシに大きく縛られる
    • out-of-order実行エンジンがレイテンシを隠せるだけの命令を十分にflight状態に保てないと、フロントエンドはバックエンドへそれ以上送れずidleになる
  • 浮動小数点suiteでは、544.nab508.namdがかなり多くのコアサイクルでループバッファを使用する
    • 508.namdは平均3.64 IPCのhigh IPC workloadで、フロントエンドthroughput要求が大きい
    • ループバッファに親和的で、op cacheを止めて省電力化できる余地がある
  • ループバッファが無効になると、op cacheがより多くのcycleでコアへ供給する
    • 523.xalanbmkでは、ループバッファなしだとop cacheが追加でコアサイクルの12%の間アクティブになる必要がある
    • 548.exchange2は平均4.31 IPCのhigh IPC workloadだが、ループバッファ有効時でもほとんど使われず、op cacheがコアサイクルの85%以上でアクティブ
    • 508.namdでは、op cacheのアクティブ比率がループバッファ有効時の56.67%から無効時の75.1%へ増加する
  • 144エントリのループバッファは、命令ストリームの大部分を収めるには小さい
    • プログラムが実行時間のかなりの部分を小さなループで費やし、かつバックエンドthroughputやレイテンシに縛られていない場合にのみ、はっきりした効果が出る可能性がある

Cyberpunk 2077での観測

  • Cyberpunk 2077の内蔵benchmarkで、ループバッファ無効化がゲーム性能へ与える影響を確認した
  • 一貫性を高めるため、Ryzen 9 7950X3DでCore Performance Boostを無効化し、全コアを4.2GHzに制限した
    • Hardware Configuration register MSR 0xC0010015のbit 25をセットした
    • RX 6900 XTは2GHzに制限した
    • benchmark設定は1080p、medium preset、upscalingなし
  • VCache dieにゲームを固定した場合、ループバッファ無効化は性能にほぼ影響しない
  • non-VCache dieに固定した場合は、ループバッファ無効化で5%の性能低下が観測されたが、原因は確認されていない
    • benchmarkは6回ほど再実行された
  • Cyberpunk 2077は平均して命令ストリームの約**22%**をループバッファが担い、予想以上にループバッファ親和的だった
    • ループバッファ無効化後、op cacheのマイクロop供給比率は62%から**82%**へ増加した
  • このゲームは、ループバッファ無効時の平均0.89 IPC、有効時の1.02 IPCで、high IPC workloadではない
    • フロントエンド帯域幅は大きな考慮事項ではない
    • バックエンド律速、あるいはbranch predictor遅延に縛られていた可能性がある
  • VCache dieで実行した場合、性能カウンタはループバッファ有効時に平均1.25 IPC、無効時に1.07 IPCを示した
    • 新BIOSで小さな性能低下も観測された
    • 155 FPS前後ではGPU側ボトルネックにより近づいていた可能性がある

コア電力カウンタ結果の不確実性

  • ループバッファ実行が電力効率を改善するか確認するため、Zen 4のcore power counterも調べた
  • instruction bandwidth benchmarkは、テスト区間でCALL/RETを使わないよう修正された
    • CALL/RETがあるとZen 4がループバッファを使わないため
  • テストは1コアに固定し、テスト配列へジャンプする前後のCore Energy Status MSRを読み、平均電力を計算した
  • Core Performance Boostは電力読み取りが大きくぶれるため無効化した
  • 旧BIOSでは、Core Energy Status MSRはop cacheからNOPを取得する場合に平均6W、ループバッファから取得する場合にははるかに低い電力を示した
  • テスト配列サイズをL2容量に収まる128KBまで増やしてop cache coverageを1%未満に下げた場合でも、平均core powerは1.5Wと表示された
    • デコーダとL2 fetch pathの使用増加が必要な状況と整合しない結果である
  • 新BIOSでは、op cacheテストが平均1.68W、L2からデコーダ中心に供給するテストもほぼ同じ電力を示した
  • AMDの電力監視機能は実測ではなく電力モデリングである可能性がある
    • BIOSバージョン間でモデリング方法が変わったか、電力モデル自体が適切でない可能性がある
    • 12V EPSコネクタなどで直接測定するハードウェアがなく、追加検証は行われていない

無効化理由と開発者視点

  • AMDがZen 4ループバッファを無効化した理由は不明
  • CPU機能はハードウェアバグのために無効化されることがある
    • Intel SkylakeのループバッファであるLSDは、SMT 2スレッド有効の短いループでpartial register accessに関連するバグのため無効化された事例がある
  • Zen 4は、AMDが高性能CPUにループバッファを搭載した初の試みであり、初実装機能の検証は難しい
  • AMDが内部的に外部へ表れないバグを発見し、予防的にループバッファを無効化した可能性がある
  • 性能影響は、op cache帯域幅が十分であるため、ほぼないか非常に小さいとみられる
  • 電力影響は不明だが、小さく測定も難しい可能性がある
  • AMDはループバッファをProcessor Programming Referenceの一文以外ほとんど文書化も宣伝もしていない
    • Intelが自社loop bufferをしばしば文書化し、開発者が活用できるよう最適化ガイドで推奨するやり方とは対照的
  • Zen 4ループバッファは、容量の小ささとCALL/RET制約のため、op cacheほど有用ではない限定的な機能である
  • 古いBIOSでZen 4ループバッファを意識して最適化するなら、次の条件を考慮できる
    • ループを144 micro-ops未満に保つ
    • 物理コアを2スレッドで共有するなら、その半分程度を考慮する
    • 小さなループ内で呼ばれる関数は、CALL/RETを避けるためinlineを検討する
  • こうした最適化をしても、見返りはほとんどない可能性が高い

1件のコメント

 
GN⁺ 2024-12-02
Hacker News の意見
  • この機能は、まだ公表されていないハードウェア脆弱性を防ぐために無効化されたのではないか、という推測が浮かぶ

    • 記事でもおおむね同じように推測している: Zen 4は、AMD が高性能 CPU にループバッファを入れた初の試みであり、初回実装の検証は常に難しい
      AMD 内部で誰も遭遇していなかったバグを見つけ、過度に慎重を期してループバッファを切ったと想像しても無理はない。このコアのライフサイクルのこの時点で、AMD が Zen 4 のフロントエンドに手を入れるほかの理由はあまり思い浮かばない
    • 実際には、もっと多くのものが無効化された可能性もある。数値がかなり意外だ: Cyberpunk 2077 を VCache ダイで実行した場合、ループバッファを有効にすると平均 IPC が 1.25、無効にすると 1.07 と性能カウンタには出るにもかかわらず、新しい BIOS ではわずかな性能低下がある
      個人的にはマイクロコード緩和策の匂いがするが、当然ながら CVE を待つ必要がある
    • ひっそり無効化すること自体も大きなリスクだ。問題の深刻さを認識しており、パッチするほど深刻だと判断したというシグナルになるからだ
      脆弱性を公開しなければ、影響を受ける側は純粋な偏執以外に対応を始める手段がない。脆弱性公開は、責任を最終ユーザーに転嫁する方法でもある。アップデートしていないなら文句を言うな、という形だ。公開が製品責任につながることはまれで、Meltdown や Spectre でもそうした責任問題があった記憶はない。だから AMD が意図的に隠していると断定はしない
    • 正解のように思うが、これ以上は言えない :(
  • 記事は、ループバッファには性能上の利益も電力上の利益もないことを示唆しているように見える
    だとすると、「エンジニアチームが数か月かけて光り輝く新機能を作ったが実際の利益はなく、それでも誰かが面子を保とうとして出荷した」という古典的なケースかもしれない。ソフトウェアチームでも、レガシーな肥大化をなくして性能を上げると言ってコードベースを書き直したものの、終わってみればコード行数は増え、性能は悪化する、ということを見たことがある。どちらの場合も出荷すべきではなかった

    • それでも出荷した理由は、ファームウェアアップデートで無効化でき、設計の途中で物理的なハードウェア配置を大きく変えると、もっと悪い影響が出た可能性が高いからだ
    • コアにすでに入った後で、ほとんど役に立たないと気づいたのなら、それを取り除くこと自体が明らかなリスクだ
    • 記事でも消費電力を全般的に測定するのは難しかったとしているので、この機能に何の影響もないと結論づけることはできないし、実際そうすべきではない
      AMD のエンジニアリングチームが、何の価値もないハードウェア機能に面積と電力を使わせるほど原則がないとは考えにくく、ここでは Chips 'n Cheese が影響を測定できなかった可能性のほうを重く見たい
    • かなり有名なハードウェア企業で働いているが、ソフトウェア側は、一部の狭いユースケースや狙ったベンチマーク以外では利益が十分に証明されていないことでも、何かをすることにこだわっている
      非常にもどかしいが、誰も事前調査に時間をかけようとしない。新プロジェクトを押し進めるほうが上層部を満足させやすく、質問も受けにくい
    • 電力ベンチマークが正確だという別の可能性もある。バッファは電力を節約していたが、その後マイクロコードレベルで通常経路のほうをより省電力にする、より良い最適化を見つけたため、バッファがむしろ電力を食う装置になったのかもしれない
  • 記事でいちばん興味深い段落はここだ: Zen 4 のループバッファを見る最良の観点は、AMD にはエンジニアが何かを試せる余裕能力があるというシグナルだということ
    今回は成果がなかったのかもしれないが、エンジニアに低リスク・低影響の機能で実験させるのは、自信を積み上げる良い方法だ。今後、そうした自信をもっと見られることを期待したい

  • 「奇妙なことに、non-VCache ダイに固定すると、ループバッファ無効化時にゲーム性能が 5% 落ちる。理由は分からない」という部分は、より細かな電力測定があれば熱/電力バジェット関連かどうか判断できるのではないかと思う
    この機能は電力を節約する意図にも見える

    • ここでは詳細情報が十分ではない。Ryzen チップの2番目の CCD は、non-X3D チップでも1番目より選別品質が低く、チップごとにすべて異なる
      私の non-X3D チップの CCD0 コアの大半は 5.6〜5.75GHz まで行くが、CCD1 コアは 5.4〜5.5GHz で頭打ちになる。Zen 4 の V-Cache チップはクロックのペナルティが大きいが、キャッシュがそれ以上に補っている。同じチップの CCD1 で機能を有効にした状態と無効にした状態の両方をテストしたのか、セキュリティ修正のようなほかの変更を切り分けようとしたのかを見る必要があるが、記事では自ら「いいえ」と認めている。きちんとやるには、機能が有効な BIOS でこの機能だけを無効化する方法を見つけ、同じチップで両方をテストする必要があり、それでも別の分岐条件のせいで結果が正確でない可能性がある。全体の性能プロファイルがあれば精度は上がるだろうが、おそらく AMD のエンジニアだけができることだと思う
    • テストした2つの UEFI バージョンのどこかの間で無効化されたと言っていた。ほかの変更も含まれていたはずなので、測定は厳密な A/B テストではない
  • 実際に差を生むには小さすぎ、非常に特定の状況でしか意味がなかったようだ。もっと大きくすれば、得られる利益に比べて実装コストが高すぎたのだと思う
    とはいえ一部のワークロードでは多少のリグレッションがあるだろうが、AMD は発売後に小さな性能改善も行ってきた。Zen 4 では単に BIOS オプションにすべきだった。そうしなかったように見える点は、バグやセキュリティ問題の可能性を示唆している

    • ほとんどのユーザーが気づかないがフロントエンドを複雑にする機能をひっそり無効化したというのは、ハードウェアバグの公開を避けるか遅らせつつ、緩和策はすでに配布しようとして、このチキンビットを引いたという感じがする。いまいましいベンダーたち、いつになったら学ぶのか
  • 逸話的には、1979年の 68000 と1982年の68010の数少ない違いの一つが「loop mode」、つまり6バイトのループバッファの追加だった

    • それよりはるかに重要なのは、MMUサポートを修正した点だった。元の68000はページフォールトから復帰するのに必要な一部の状態を失ってしまい、回避策は不格好で高価だった
      CPUを2つ、1サイクルずらして実行し、2つ目のCPUに復旧可能な割り込みを注入する方式だった。それでもMMUがあり、32ビット命令セットと24ビットアドレスバスを持つCPUが欲しいなら、当時の代替案より安かったようだ。本当に荒々しい時代だったのだろう
    • 興味深い。小さなループバッファとしては GreenArrays Forthコア がかなり気に入っている
      18ビットワード1つに命令が4つ入り、あるオペコードはループカウンタを減らしてからワードの先頭に戻る。その場合、かなり高速に実行できる
    • 68010のループバッファはほとんど役に立たなかった。6バイトしかないだけでなく、命令も2つしか入らなかったためだ
      そのうち1つはループ命令(DBcc)でなければならないので、ループ本体は単一命令である必要があった。実際に速くなり得るのは、最適化されていないmemcpyくらいがほぼすべてだった
  • Cortex-A15ではこれが 中核的な設計機能 だという点が興味深い。他のチップで効果の数値があるのか気になる
    コンソールのように設計寿命が長いデバイスでは、少なくとも最適化対象としても使えそうだ

    • 私も気になる。どんな RISCアーキテクチャ でも、ループバッファから得られる利得は比較的小さいだろうと予想している
      RISCの要点は、命令のフェッチとデコードがはるかに簡単、あるいはほとんど些細なものだというところにあるから
  • 7950X3Dを持っているが、Skylake 6700Kからアップグレードしたものだ。どうやら無意識のうちに、ハードウェアループバッファがソフトウェアで無効化されたチップ に引かれるらしい

    • いつか新しいマシンを買うなら、事前に教えてほしい。こちらが避けられるように!
  • 興味深い記事だが、ループバッファがダイ上で どれくらいの面積 を占めるのか分からない
    将来のチップで取り除くなら、その面積をより大きなL2キャッシュのような、もっと有用なものに使えるのか気になる

    • 最近のチップの多くは、床面積よりも 配線制約 のほうが大きいと思う。機能はものすごくたくさん作れるが、そこへ電力と正規化された信号をすべて供給するのが本当に苦行だ
    • 私の理解では、フロントエンドのかなり小さな最適化だ。そもそもエントリ数が多くなく144個なので、節約される面積はおそらくごくわずかだろう
      理論上、ループバッファはタイトなループで電力を節約したり性能を上げたりできる。実際にはどちらもできていないように見え、AMDはZen 5で完全に削除した
    • 図を見ると、ループバッファはいずれにせよ存在する マイクロオペレーションキュー と同じ記憶領域を使っているようだ
      それが正しければ筋が通っており、面積コストは追加の制御ロジック程度だ。最も高くつく部分は、そもそもループを検出することだと思うが、キューサイズに比べればかなり小さいだろう
    • コアあたり 144個のマイクロオペレーションエントリ とある。何バイトなのかは分からないが、最近のL2キャッシュはコアあたり約1MBなので、ループバッファのダイ面積がほとんどストレージだと仮定しても、目に見える差はないだろう
  • 「電力」セクションの分析は、秒間実行命令数で割っていないように見える
    このループバッファの利点を見るには、秒あたりのエネルギー、つまり電力(ワット)ではなく 命令あたりのエネルギー を見る必要がある可能性がほぼ確実だ

    • 命令ごとにかかるクロックサイクル数は異なり、Zen 4からZen 5のようなアーキテクチャ世代間でも変わる。そのため、ワークロードが正確に同じ サイクルあたり命令数 を生まない限り実現可能ではないが、マルチスレッディングとタスク処理のため不可能だ
      順序やRAMの内容でさえ、すべてを変え得る。オンの場合とオフの場合を数百回実行すればある程度切り分けられるかもしれないが、非常に時間がかかり、それでも100%正確ではない。機能を切るだけでコードが別の分岐を取り、すべての配置が変わる可能性がある。この問題を具体的に知っているわけではないが、機能を切ると負荷が整数ユニットからFPUやGPUへ移ったり、命令5個が消える代わりに2個が追加されたりする例を見たことがある