◆CCX/Inter-Core
Zen 2世代ではChipletアーキテクチャを採用した結果、CPUダイ(CCD)とI/Oダイ(cIoD)が別々になった。Ryzen 7 3700とかの場合はこんな感じ(Photo18)。CPUダイが2つのRyzen 9 3900Xの場合はこんな感じ(Photo19)である。こうなると、例えばあるThreadが別のThreadを生成した際に、そのThreadがCCXを跨いだり、CCDを跨いで稼働したりすると、その2つのThreadの間で猛烈なメモリ参照が発生する事になり、システムの性能を著しく落とすことになりかねない。
それもあって、Windows 10のMay 2019 UpdateにはTopology Awarenessと呼ばれる機能が内蔵された。要するにあるThreadから生成されたThreadは、特に指定が無ければ同じCCXで動かすように生成されるというものだ。アプリケーションの中には、相互にメモリ参照なんぞすると猛烈に遅くなることを理解した上で、きちんと全てのコアに負荷が分散するようにThreadを生成したいものもあり、こうしたものはきちんと全てのコアで稼働するようになっている。
Photo20にはもう一つ、CPPC2に関する記述もある。こちらはCCXの構成とかには関係ない話であるが、ACPIは2014年にリリースされたACPI 5.1で、CPPC(Collaborative Processor Performance Controls)という機能が追加された。このCPPCに続き、ACPI 6.0には改良版のCPPC2という機能が追加された(*1)が、案外にこのCPPC2の実装が遅れていた。Zen 2ではこのCPPC2をサポートしており、またWindows 10のMay 2019 UpdateもCPPC2をサポートした事で、従来30ms程度要していたClock Selectionを1~2msまで短縮できたという話である。これによる性能改善であるが、Topology AwarenessではRocket Leagueで15%程度のフレームレート改善が、CPPC2 SupportではPCMark 10のApp Launchが6%高速化された、としている(Photo21)。
さてこのCCX/Inter-Core構造の性能をちょっとSandraを利用して確認してみたい。
まずグラフ32がInter-Core EfficiencyのOverallである。ことLatency(折れ線)に関してはBest/Worstでそれほど差が無いが、Bandwidthが極端に異なる。まぁこの傾向は一般的なので不思議ではないのだが、このBestとWorstで極端にBandwidthがことなるのがRyzen 9 3900Xの特徴である。ちょっとグラフ32におけるBandwidthの比をまとめると
Core i9-9900K(DDR4-2666) | 4.7倍 |
Core i9-9900K(DDR4-2933) | 5.0倍 |
Ryzen 7 2700X | 8.1倍 |
Ryzen 7 3700X | 12.8倍 |
Ryzen 9 3900X(DDR4-2666) | 20.3倍 |
Ryzen 9 3900X(DDR4-3200) | 17.7倍 |
といった具合に差が極端である。ついでに言えばWorstの時のBandwidthが10GB/secを切っているあたりもCore i9-9900Kとの大きな特徴と言える。
ではまずBandwidthについて。グラフ33はBest Caseであるが、これは要するに同じCCDの中、あるいは同じCCXの中での通信である。ここでちょっと気になるのが、Ryzen 7 3700Xの帯域の低さである。64KB×4=256KBだから、問題なくL2/L3に収まる範囲であり、一つのCCX内であればL3経由での転送となる。問題は異なるCCX間でのやり取りで、この場合片方のCCXのL3から、もう片方のCCXへのL3への転送になるのだが、これがRyzen 7 2700Xに及ばないということは、ひょっとすると同じCCD内の2つのCCX間の通信も、実際にはcIOD内のData Fabricを経由している可能性が高そうな感じである。
何を言っているかといえば、当初は同一ダイ上の2つのCCX間の通信は、図1の様に直接ダイ上で完結すると考えていたのだが、どうもそうではなく図2の様に、cIODダイ上のData Fabric経由で通信を行っているという様に見えるという事だ。Ryzen 7 2700Xの場合は、このData Fabricそのものも同じダイにあったからBandwidthもそれなりに確保できたのだが、第3世代Ryzenではそういう訳には行かないようだ。
この方式、インプリメント的には一番シンプルだが、当然性能へのインパクトが馬鹿にならない。それもあって、当初筆者はCCXを8コアに拡張する、あるいはCCD上に(2つのCCX間をつなぐ目的だけに)Data Fabricを用意するのかと考えていたのだが、逆にこの程度の性能へのインパクトを許容し、それよりもシンプルに構成する、という実装を選んだことになる。
ちなみにこのグラフ33で、にも関わらずRyzen 9 3900Xの数値が異様に良いのは、なんせコアの数が圧倒的に多い分、同時に転送を行える組み合わせが多く、その分帯域が増えて見えているだけと考えられる。
ではWorstは? とうとこんな具合(グラフ34)。やはりCCXを跨ぐのはオーバーヘッドが大きいようで、Ryzen系が全滅しているのはまぁ当然というべきか。逆にL3があるいみUnifiedというか妙なパーティションの無いCore i9-9900Kの数字が高いのも、これも当然である。この範囲で言えば、Zen 2世代はあまりZenに比べてアドバンテージが無いというか、Data Fabricの制御を別チップにしている分オーバーヘッドが大きいのは当然とは言える。
ではLatencyはどう変わったか? というのがグラフ35と36である。これは各々のコア間の通信のLatencyの頻度分布を取ったものであるが、まずはBest Caseのグラフ35を。一番小さい10ns台は、同じコア上の2つのThread間の通信で、これだとL1かL2で通信可能だから当然一番高速である。これに関してはRyzen系もCoffee Lakeもほぼ同じである。
さて、次であるが
25nsあたり:第3世代Ryzenの、同じCCX内のコア間の通信
40nsあたり:Ryzen 7 2700Xの、同じCCX内のコア間の通信と、Coffee Lakeの異なるコア間の通信
70~90ns:第3世代Ryzenの、異なるCCX内のコア間の通信
120ns:Ryzen 7 2700Xの、異なるCCX内のコア間の通信
となっており、第3世代RyzenはRyzen 7 2700Xと比較して同じCCX内の通信のLatencyが15nsほど、異なるCCX間のコア間通信が30~40nsほど高速化されている事がここから判断できる。
ちなみに第3世代Ryzenで異なるCCX間のコア間通信のLatencyにバラつきがあるのは、Infinity Fabricの速度が異なるためである。紫はDDR4-3200で、一方翠と黄色はDDR4-2666になっている。Photo22にもあるように、InfinityFabricの速度はfclkというクロックソースで決まるが、DDR4-3773まではDDR4の転送速度(memclk)と1:1に連動しており、なのでDDR4-3200を利用すると帯域が上がるだけでなく相対的にLatencyも削減できるという事になる。
Worst Caseのグラフ36でも構図は大きくは変わっておらず、若干Latencyの大きい山の頻度が増えたかな、と言う程度。Data Fabricのコントロールを別チップにしたことでBandwidthでは若干のデメリットが生じているが、Latencyでは大きく改善されている事が確認できた形だ。
(*1)厳密に言えば、ACPI 5.1のSpecificationの中に既にCPPC2への言及はあるのだが、詳細が規定されていない。これが入るのはACPI 6.0以降である。