最初にお断りしておくと、今回の記事はドイツのMatthias Waldhauer氏(@Dresdenboy)との共同作業である。

同氏はAMDの次期プロセッサーZenとK12の関係を自身のブログでいろいろ考察しているが、筆者の記事を機械翻訳しても意味が通じないということで直接メールで質問をいただき、その結果を自身のブログに反映している。

これに関してメールでやり取りしている最中に、いろいろ興味深い情報を教えていただいた。これを記事化することも承諾いただいたので、この情報をベースにZenの内部構造の推察を試みてみたい。

ちなみにWaldhauer氏が得た情報に基づく記事はこちらである。当然ながら、内容は氏のものと重複する部分があることを最初にお断りしておく。

AMDのパッチからzenと思わしき記述が見つかる

ソフトウェア開発のためのソースコード管理サービスであるGitHubにあるGCC(GNU Compiler Collection)には、さまざまなアーキテクチャー向けのパッチが常に投稿され続けている。

これは新アーキテクチャーが出てくるたびに必ず発生するのだが、2015年10月6日にznver1というパッチがAMDのVenkataramanan Kumar氏により投稿された(関連リンク)。

Kumar氏はAMDの技術者であるとともにGNUの貢献者でもある。ビジネス特化型SNSのLinkedInにあるKumar氏の経歴によれば、過去4年間AMDのGCCコンパイラチームで働いており、主にGCCでの新命令のサポートや性能分析/改善の作業を行なってきたとしている。

Kumar氏のパッチは、14のファイルに対して、1239の追加と29の削除を行なうものになっているが、まず最後のgcc/doc/invoke.texiに対する修正を見ると以下のようになっており、znver1はZenコアの初代(Version 1)を指しているのは明白である。

+@item znver1

+AMD Family 17h core based CPUs with x86-64 instruction set support. (This

+supersets BMI, BMI2, F16C, FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX,

+SHA, CLZERO, AES, PCL_MUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3,

+SSE4.1, SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT, and 64-bit

+instruction set extensions.

ちなみにこの記述を見るとZenは17hとなっている。Excavatorコアが15hなので16hが飛んでいる。これはおそらくAMDが10月に発表した“Merlin Falcon”ことAMD Embedded Rシリーズに充てられているものと思われる。

ただこの段階では、単にサポートされる命令しかわからない。もう少しディテールが示されているのは、新たに追加されたgcc/config/i386/znver1.mdである。やや長いのだが抜粋させていただく。

+(define_attr "znver1_decode" "direct,vector,double"

+ (const_string "direct"))

+

+;; AMD znver1 Scheduling

+;; Modeling automatons for zen decoders, integer execution pipes,

+;; AGU pipes and floating point execution units.

+(define_automaton "znver1, znver1_ieu, znver1_fp, znver1_agu")

+

+;; Decoders unit has 4 decoders and all of them can decode fast path

+;; and vector type instructions.

+(define_cpu_unit "znver1-decode0" "znver1")

+(define_cpu_unit "znver1-decode1" "znver1")

+(define_cpu_unit "znver1-decode2" "znver1")

+(define_cpu_unit "znver1-decode3" "znver1")

+

+;; Currently blocking all decoders for vector path instructions as

+;; they are dispatched separetely as microcode sequence.

+;; Fix me: Need to revisit this.

+(define_reservation "znver1-vector" "znver1-decode0+znver1-decode1+znver1-decode2+znver1-decode3")

+

+;; Direct instructions can be issued to any of the four decoders.

+(define_reservation "znver1-direct" "znver1-decode0|znver1-decode1|znver1-decode2|znver1-decode3")

+

+;; Fix me: Need to revisit this later to simulate fast path double behaviour.

+(define_reservation "znver1-double" "znver1-direct")

+

+

+;; Integer unit 4 ALU pipes.

+(define_cpu_unit "znver1-ieu0" "znver1_ieu")

+(define_cpu_unit "znver1-ieu1" "znver1_ieu")

+(define_cpu_unit "znver1-ieu2" "znver1_ieu")

+(define_cpu_unit "znver1-ieu3" "znver1_ieu")

+(define_reservation "znver1-ieu" "znver1-ieu0|znver1-ieu1|znver1-ieu2|znver1-ieu3")

+

+;; 2 AGU pipes.

+(define_cpu_unit "znver1-agu0" "znver1_agu")

+(define_cpu_unit "znver1-agu1" "znver1_agu")

+(define_reservation "znver1-agu-reserve" "znver1-agu0|znver1-agu1")

+

+(define_reservation "znver1-load" "znver1-agu-reserve")

+(define_reservation "znver1-store" "znver1-agu-reserve")

+

+;; vectorpath (microcoded) instructions are single issue instructions.

+;; So, they occupy all the integer units.

+(define_reservation "znver1-ivector" "znver1-ieu0+znver1-ieu1

+ +znver1-ieu2+znver1-ieu3

+ +znver1-agu0+znver1-agu1")

+

+;; Floating point unit 4 FP pipes.

+(define_cpu_unit "znver1-fp0" "znver1_fp")

+(define_cpu_unit "znver1-fp1" "znver1_fp")

+(define_cpu_unit "znver1-fp2" "znver1_fp")

+(define_cpu_unit "znver1-fp3" "znver1_fp")

+

+(define_reservation "znver1-fpu" "znver1-fp0|znver1-fp1|znver1-fp2|znver1-fp3")

+

+(define_reservation "znver1-fvector" "znver1-fp0+znver1-fp1

+ +znver1-fp2+znver1-fp3

+ +znver1-agu0+znver1-agu1")

ここからかなりいろいろなことがわかる。まず冒頭のDecoders unitだが、Zenには4つのデコーダーが搭載され、いずれもFast PathとVector Typeの両方の命令をカバーするとしている。

Fast Pathは命令構造が簡単な、インテルで言うところのSimple Decoderでカバーされるタイプ。一方Vector TypeはMicrocodeを参照する、インテルで言うところのComplex Decoderでカバーされるタイプだ。

つまりK7/K8世代と同じく、すべての命令が各々のデコーダーで取り扱い可能で、しかもそれが4命令/サイクルで実装されているのがわかる。

もっとも、Vector Pathに関しては“Currently blocking all decoders for vector path instructions as they are dispatched separetely as microcode sequence.”というあたり、実際にVector Pathを解釈するユニットは1つしかないようである。一方Direct Pathに関しては4つのデコーダー自身で解釈可能となっているようだ。

さて、次はALU（演算ユニット）であるが、これもIEU0～IEU3の4つが用意され、またIEU0～IEU3までは完全に同じ構成になっているようだ。

同様にAGU（アドレス生成ユニット）はAGU0とAGU1の2つが用意され、これも機能は同じようになっている。GPUもそうでFP0～FP3の4つが用意され、いずれも同等に設定されているらしい。

ここでイレギュラーなのが、先にVecor Pathを通った命令である。これに関しては他の命令とは排他に近い形で実行されるらしい。こうしたメカニズムはあまりこれまで見ることができなかったが、理由はなんとなくわかるので、これは後述する。

→次のページヘ続く （パッチから推定するZenの内部構造 ）