AMD HEROES

twitter
facebook
line

Ryzen 5000シリーズはなぜ高速なのか? 秘密はZen 3の内部構造にあり AMD CPUロードマップ(2/5)

大原雄介(http://www.yusuke-ohara.com/) 編集●北村/ASCII

※この記事はASCII.jpからの転載です(文中リンクはASCII.jpの記事に飛ぶことがあります)

スケジューラーの構造を大きく変更した
バックエンド

次がバックエンドである。先にも書いたが、Integer(整数演算)が最大8イシュー、Float(浮動小数点演算)が最大6イシューとなり、その意味ではどちらも同時実行命令数は増えてはいるのだが、やや筆者の予想と異なる最適化の方向性になっていた。

バックエンドの構成。スケジューラーの構造変更が最大のポイントかもしれない

このレベルでの最大の相違点はスケジューラーの変更だ。Zen/Zen 2は、AGUとALUを別々に扱うという仕組みで、であれば7つの発行ポート全体をカバーするスケジューラーにした方が効率が良いという判断であった。この発想はインテルとかなり近い。これに対してZen 3では以下の4つに分解されることになった。

Zen 3のスケジューラー
Scheduler 0 ALU0+AGU0
Scheduler 1 ALU1+AGU1
Scheduler 2 ALU2+AGU2
Scheduler 3 ALU3+BRU1

これはなぜかと言えば、おそらくだが実際に実行中のプロファイルを取ってみると、予想以上にメモリー演算が多かったのだろう。そもそもRISCの場合、演算命令はレジスターに対して行なう形で、メモリーアクセスが可能なのはロード/ストアー命令に限られている。だからこそAGUとALUは別々に動かしても問題ないという発想である。

これはx86も同じで、x86なりx64そのものはCISCであるが、Micro-Opに変換した段階でRISC風になっているため、ALU命令そのものはすべて内部のレジスターに対して行なう形となり、これとは別にメモリーからレジスターへのロード命令が自動的に生成される形になる(ストアーに関しては原則として、x86/x64でも明示的に命令を発行する必要がある)。

ただ、そうした「メモリーからのロード+演算」の組み合わせが少なければ、ALUとAGUを別々に駆動しても問題ないのだが、その頻度があまり多いようだと、ALUとAGUがペアになって動く方が効率が良いことになる。

そもそも、先のフェッチ/デコード段の概要を説明する画像で、Dispatchから出てくるのは「Macro-Ops」であることに注意されたい。これはインテルの言うMacro-Opsと同じもので、要するに複数のMicro-Opsの組み合わせである。要するにフェッチの段階では

x86 ADD reg, Mem メモリー上の値を加算するx86のADD命令

だったのがデコードの後では

Micro-Op load Mem, reg1 reg1にMemの内容をloadするMicro Op
add reg, reg1 regにreg1の内容を加算するMicro Op

に変化し、これがDispatchを出るときには、以下のようにまとめられるわけだ。

Micro-Op load&add reg, reg1, Mem 上の2つのMicro OpをまとめたMacro Op

今まではスケジューラーの中で、このMacro-Opをもう一度ほぐしてALUとAGUに命令を投入していた形だが、そうであれば最初からほぐさずにスケジューラーでは1つのMacro Opとしてスケジューリングを行ない、それを発行する段階で2つに分離した方が効率が良いと判断されたようだ。このあたりはK7→K8の構造の推移に非常に近い。

下の画像は10 issue per cycleとあるが、これはStore Data×2が図には入っていないためだ。

整数演算の仕組み。AVX命令を実行しながら並行してレジスターの内容の保存が可能になった。したがって、スループットは0.5だったのが1になったことになる

実際にはStore Dataの作業はロード/ストアーユニット側なのでここに計上するのは間違っているのかもしれないが、整数演算系で1サイクルあたり2つのストアーが可能(従来は1つ)というのは、特にメモリーに書き出しが多いアプリケーションでは性能向上につながることになる。

この記事もおすすめ

PAGE TOP