押さえておきたいUMA(Unified Memory Address)とNUMA(Non Unified Memory Address)
EPIC/ThreadRipperだけでなく、Intel Xeon E5以上とか最近のXeon Scalableにも共通する話だが、UMA(Unified Memory Address)モードとNUMA(Non Unified Memory Address)モードという2種類の動作モードが利用できる。
図4は2つの動作モードを簡単に説明したものだ。物理的にメモリとプロセッサが2つに分離されている状態で、通常のUMAモードだと、どちらのプロセッサもどちらのメモリ領域を直接アクセスできる。これに対し、NUMAモードではプロセッサは自分に直接接続されているメモリ領域しかアクセスできない。例えばProcessor #1がMemory Region #2をアクセスしたいと思ったらプロセッサ間通信でProcessor #2に領域をアクセスしてもらうという間接的なアクセスになる。
なんでこんな方式があるかといえば、特に4 Socket以上のシステムにおいては、Cache Coherencyを取るためのSnoopingの手間がしゃれにならないことが挙げられる。また、複数のProcessorと複数のMemory Blockの間で高いスループットを取るためのInterconnectを用意するとコスト高になるためだ。
図4の上でいえばUMAの場合、Processor #1と#2はメモリ書き換えの際にはお互いにSnoopingを実施しないといけないし、InterconnectはProcessor #1→Memory Region #2あるいはProcessor #2→Memory Region #1のアクセスに備えて、Memory Accessよりも大きな帯域にしないとそこがボトルネックになってしまう。
ところがNUMAにすると、まずSnoopingが不要になる(正確に言えばProcessor #1/#2内部のコア同士でのSnoopingは必要だが、#1/#2の間のSnoopingは不要)だし、Interconnectはメモリアクセスよりも低い帯域であっても、それがボトルネックになりにくい(なるかどうかはアプリケーション次第)。
実はWindowsもすでにNUMAに対応済である。Windows系の場合、Windows Server 2008/Windows Server 2003、Windows XP/Windows Vistaまでの世代はNUMAに対応しない(正確に書けば、1つのOSで複数のNUMAノードをサポートできない)。ただし例外はあって、例えばWindows 2000 Datacenter ServerそのものにはNUMAのサポートが無いが、これを採用したOEMメーカーが自身でNUMAサポートを提供するといった形で提供されていた。
ところがWindows 7やWindows Server 2008 R2以降ではNUMAが標準でサポートされるようになった。アプリケーションそのものは、UMA/NUMAを意識せずに稼動させることができる(もちろん性能へのインパクトはある)。
ThreadRipperの場合、デフォルトはUMA(Distributed Mode)となっており、この場合すべてのコアがすべてのメモリにアクセス可能(Photo09)だが、それとは別にNUMA(Local Mode)も搭載される。これの性能へのインパクトだが、例えばPhoto11のような結果がAMDから示されている。
UMAを利用した場合、1つのコアからアクセスできるメモリチャネル数が増えるので、帯域は上がりやすい(NUMAだとプロセッサによりワンクッション入るので、その分帯域は下がる)。ただしLatencyは、Cache Coherencyを考えなくて良い分NUMAの方が低Latencyで動作する。
帯域を取るか、Latencyを取るか、というのはアプリケーション次第で損得がはっきりすると思う(あるいは、変わらないというアプリケーションもあるだろう)が、これは実際に試して判断したいと思う。
EPYCの場合の結果がこちら(Photo12)。これだけ差があると、NUMAにすべきか否かは、事前にアプリケーションを走らせ、その結果で見ることになる。サーバーではごく当然の準備ではあるのだが、ついにデスクトップでもそうした状況になり始めた、というのはある意味凄いことである。
ちなみにこのUMA/NUMAの設定であるが、BIOS Setupから可能である(Photo13)。Ryzen MASTERでも可能(Photo14)だが、設定変更後にはシステムリセットが必要なあたり、BIOS Setupで行うのとそれほど手間は変わらなかったりする。
一部のゲーム向けに用意された「Legacy Compatibility Mode」(レガシー互換モード)
ところでNUMAのついでにCompatibility Mode(Photo14で右下の設定項目)についても触れておく。特にRyzen ThreadRipper 1950Xともなると論理コアが32個にも達するため、一部のゲームでは動作しなくなる場合がある(ゲーム側で扱える論理コアの数を超えてしまう)という問題が報告されている。
ファーストインプレッションでも紹介した通り、今回だとF1 2016がそうだが、ほかにDiRT Rally、Far Cry、Far Cry Primalなどがこれに該当するとされる。
この解決法としてLegacy Compatibility Modeが用意されており、これをオンにするとコア数が半減する。具体的には以下のようになる。
- Ryzen ThreadRipper 1950X : 4core+4coreの8core/16Thread NUMAモードとして動作
- Ryzen ThreadRipper 1920X : 3core+3coreの8core/12Thread NUMAモードとして動作
1950Xが1900X相当の、しかもNUMAモードとして動作するという訳だ。ただF1 2016のところでも書くが、実はNUMAモードに設定するだけでF1 2016では動作してしまったので、今回Legacy Compatibility Modeは試していない。
テスト環境の紹介(前回からの補足)
座学はこのあたりにして、テスト環境について紹介する。基本的には前回に順ずるというか、前回と同じなのだが、これに加えてCore i7-7700Kの結果も追加している。ことゲーム向けという観点では、Core i9-7900XよりもCore i7-7700Kの方が高いスコアを出しているシーンも珍しくないので、こちらとの比較も有用と考えての事だ。テスト環境は表1の通りである。
CPU | Core i7-7700K | Core i9-7900X | Ryzen 7 1800X | Ryzen Threadripper 1920X Ryzen Threadripper 1950X |
---|---|---|---|---|
M/B | ASUS PRIME Z270-A (BIOS 1009) |
MSI X299 GAMING M7 ACK (BIOS 7A90c12) |
ASUS CROSSHAIR HERO VI (BIOS 1403) |
ASUS ROG ZENITH EXTREME (BIOS 9960) |
Memory |
Kingston KVR26N19S8/8 (DDR4-2666 CL20 8GB×4) |
G.Skill F4-3200C14-16GTZR DDR4-3200 CL14 8GB×4(DDR4-2666 CL16で利用) |
||
GPU |
NVIDIA GeForce GTX 1080 Frontier Edition (GeForce Driver 384.94 WHQL) |
|||
Storage |
Intel SSD 600p 256GB(M.2/PCIe 3.0 x4) (Boot) WD WD20EARS 2TB(SATA 3.0)(Data) |
|||
OS & Software |
Windows 10 Pro 64bit 日本語版 Version 1703 Build 15063.413 .NET CLR 4.0.30319 Java Version 1.8.0_132 64bit |
またThreadRipperに関してはUMAモードに加えてNUMAモードでの評価も行ってみた。そんなわけでグラフ中の表記は以下の7種類が入り乱れている。
- i7-7700K:Core i7-7700K
- i7-7900X:Core i9-7900X
- R7 1800X:Ryzen 7 1800X
- TR 1920X:Ryzen ThreadRipper 1920X UMAモード
- TR 1920N:Ryzen ThreadRipper 1920X NUMAモード
- TR 1950X:Ryzen ThreadRipper 1950X UMAモード
- TR 1950N:Ryzen ThreadRipper 1950X NUMAモード
なお、直接評価と関係はないのだが、Core i9-7900Xの評価中に、水冷ヘッドから異音がするようになり、どうしたものかと思ったのだが、SilverStoneからSST-TD03-Eを提供いただき、これを利用してテストをCompleteできたので紹介しておきたい(Photo15、16)。それ以外は前回と全く同じである。