昔と比べてCPUのコンピューティング能力は急成長を遂げており、求められるメモリ性能も急速に高まり続けています。CPUとGPUのコンピューティング能力が急上昇している中、アドレス指定可能なシステムメモリの不足により、AI学習のような多くのワークロードが制約を受けているというのが現状です。仮想メモリ(SSDベースのスワップスペース)、OS層では有用かもしれません(メモリ不足の問題によるシステムのクラッシュを防止できます)。しかし、高性能ワークロードでメモリ容量を増やす目的には適していません。
この問題へのテクノロジーによる対処方法として、Compute Express Link™(CXL)の導入が挙げられます。CXLを導入すると、メモリプールを複数のコンピューティングノード間で接続・共有できるようになり、ローカルDRAMよりも桁違いにメモリを拡張することが可能になります。また、プロセッサキャッシュやGPUローカルメモリ(高帯域幅メモリ(HBM))から、難解でコヒーレントな非常に低速の遠隔メモリに至るまで、パフォーマンスと局所性に基づいてメモリを細かく階層化する必要があります。
通常、このようなメモリ容量の拡張はDRAM + CXLに関してであり、ストレージやNVMe SSDにはほとんど影響しないと思われています。しかし、それは正しくありません。SSDが階層型メモリを認識する必要があり、SSDの最適化によって高性能ワークロードのパフォーマンス、レイテンシーまたはその両方を向上できます。この用途でSSDを最適化するには、ATSとそれに関連するATCのサポートが必要になります。その詳細についてはこの記事でご説明します。
ATS/ATCとは
ATS/ATCは仮想システムで最も効果を発揮します。非仮想システムでも使用できます。ただし、この記事では簡潔に説明するため、SrIOVなどの標準的な方法により、直接割り当てた仮想システム内の仮想マシン(VM)のデータパスをトレースすることで、ATS/ATCの仕組みを詳しく説明します。以下の図を参照してください。
仮想化の大切な要素として、仮想環境で実行されていることをゲストVMが認識していないということが挙げられます。システムデバイス(SSDなど)が複数のVMではなく単一のホストと通信していると認識するため、SSDに細工を加えなくても正常に動作します。
このようなアプローチを採用した結果、メモリのアドレス指定が問題になります。ゲストOSは専用システムでの実行が想定されているため、システムメモリアドレス(SVA = システム仮想アドレス、SPA = システム物理アドレス)を使用していると認識します。しかし、実際は、ゲストOSはハイパーバイザーによってVMスペースで動作しています。VMに対しては、ローカルではあるものの、システムアドレスマッピングとはまったく異なるゲストアドレスが渡されます。ゲストOSはSVAとSPAを使用していると認識しますが、実際にはゲスト仮想アドレス(GVA)とゲスト物理アドレス(GPA)を使用しています。
ローカル(ゲスト)からグローバル(システム)のアドレス指定スキームへの変換にあたっては注意が必要です。プロセッサには、メモリ管理ユニット(MMU)とIOMMUの2つの変換メカニズムがあります。MMUはプログラムによってアドレスが直接指定されるメモリをサポートするメカニズム(SSDとは無関係です)で、IOMMUはすべてのDMA転送の変換をサポートするメカニズムです。ここではIOMMUが重要です。
図1のように、VM内のゲストOSがSSDから読み取りを行うたびに、DMAアドレスを提供する必要があります。ゲストOSにはSPAと認識されますが、実際はGPAです。DMAアドレスとしてSSDに送られるのは、GPAだけです。SSDはリクエストされたデータを送信する際、認識しているGPAとともにPCIeパケット(トランザクション層パケット(TLP)と呼ばれます。通常は512B以下のサイズです)を送信します。その際、IOMMUは送信されてきたアドレスを調べ、それがGPAであることを認識し、変換テーブルを基に対応するSPAを特定し、正しいメモリアドレスを使用できるようにGPAをSPAに置き換えます。
NVMe向けATS/ATCが重要な理由
システムにいくつものSSDやCXLデバイスがあると、アドレス変換が大量に発生してIOMMUが詰まり、システムのボトルネックになる可能性があります。
たとえば、最新のSSDは4KBごとに最大600万IOPSを実行できます。TLP = 512Bとすると、各IOは8TLPに分割されるため、4,800万のTLPを変化する必要があります。IOMMUは4デバイスごとにインスタンス化されるため、1秒あたり1億9,200万のTLPが変換されます。これだけでも大きな数字ですが、TLPは「最大512B」で、それより小さくなることもあるため、それ以上に変換数が増える可能性もあります。TLPが小さくなるほど、それに比例して変換数が増加します。
変換数を減らす方法を発見する必要があります。それを解決するのがATSです。ATSは前もって変換を要求しておき、変換が有効であれば再利用するメカニズムです。OSページが4KBである場合、各変換が8TLPに使用されるため、それに応じて変換数が減少します。ただし、ページは連続している可能性があります。ほとんどの仮想システムでは次の有効な粒度は2MBであるため、各変換は8*2M/4K = 4096の連続するTLP(TLPが512B未満の場合はそれ以上)に使用できます。IOMMUによる変換数が約200億から10万を大幅に下回るようになり、詰まりが発生するリスクが軽減されます。
NVMe向けATS/ATCのモデリング
NVMeの場合、コマンドごとに送信キュー(SQ)と完了キュー(CQ)のアドレスがそれぞれ1回使用されます。そのような(静的な)変換のコピーを保存しておくべきでしょうか? そのとおりです。それがまさにATCのメカニズムです。ATCは最も一般的な変換のキャッシュコピーを保存します。
ATS/ATCの設計に必要となる、SSDが受信するDMAアドレスパターンはどのようなものでしょうか? 残念ながら、それに関するデータや資料はありません。
私たちは、モデリングのために使用できるよう、SSDが受信したすべてのアドレスを追跡して保存するツールを構築することで、この問題に取り組みました。意義のあるデータを得るには、キャッシュ実装の有効なデータセットを表現するのに十分なデータポイントを持つ、実際のアプリケーションの有効な表現からデータを取得する必要があります。
私たちは、さまざまなデータセンターアプリケーションの一般的なワークロードベンチマークを選択して実行し、20分間のセクションごとにIOトレースを取得しました。その結果、モデリングに利用できるトレースごとのデータポイントが数億個に達しました。
下の図は収集されたデータの例です。このデータは、XFSファイルシステムを使用し、RocksDB上でYCSB(Yahoo Cloud Server Benchmark)を実行して収集されたものです。
ストレージのデータATC評価:
- 特性評価の方法:
- VMが標準的なワークロードを実行していることを前提とします。
- 各ワークロードの一意のバッファアドレスをトレースします
- バッファアドレスをSTU(2MB)の下のページにマッピングします
- ATCのPythonモデルを構築します
- ヒットレートを検証するため、トレースをモデルに再実行します
- 妥当な数のワークロードと構成で繰り返します
所見:予想どおり、複数のVMは単一のイメージよりも局所性が低くなりますが、スケーリングは線形ではありません(VMを16倍にするとサイズが4倍になります)
キャッシュの要件を算出するため、キャッシュのPythonモデルを構築して、トレース全体を再生し(数億のすべてのエントリ)、キャッシュの動作を分析しました。これにより、キャッシュサイズ(行数)、削除ポリシー、STUサイズ、モデリングに関するその他のパラメータの変更をモデル化できるようになりました。
ベンチマークごとに約1億5,000万~3億7,000万のデータポイントを分析したところ、通常、使用される一意のアドレスは数万であることが分かり、キャッシュサイズとして良好な結果が得られました。最もよく使用する2MBページ(最小転送単位(STU))にマッピングすると、ページ数は数百や数千に減少します。
これはバッファの再利用が非常に多いことを示しています。つまり、システムメモリがTB単位になったとしても、IOに使用されるデータバッファの量はGB単位なうえ、使用されるアドレスの数は数千単位であり、キャッシュに最適となります。
アドレスの再利用が多かったのは、私たちが使用したシステム構成の局所性に依存しているのではないかという懸念があったため、複数の異なるデータアプリケーションベンチマークへの追加テストを実施しました。以下の表は、上記のYCSB/RocksDB/XFSのテストの1つと、XFSを用いたMicrosoft SQL Server上のTPC-Hを比較したものです(両者のベンチマークは根本から異なります)。
TPC-Hとの相関関係:
- IOの分布が大きく異なります:
- 一意のアドレスが3.2倍です
- ただし、STUの70%に分派しています -> 局所性が高い
- キャッシュヒットレートが64エントリに収束します(RocksDBと一致)
データトレースは大きく異なりますが、キャッシュサイズが十分に大きい場合(たとえば、わずか64行以上)、同じヒットレートに収束します。
他の複数のベンチマークでも同じ結果が検証されていますが、簡潔にするためにここでは省略します。
サイズへの依存:
- 使用ベンチマーク:YCSB WL BとCassandra
- キャッシュ:4ウェイセットアソシエイティブ
- アルゴリズム:ラウンドロビン
- 所見:
- 予想どおり、ヒットレートはSTUのサイズに大きく依存します
- STUのサイズが大きくなるほど、ヒットレートが高くなります
- すべてのデータが同じように作成されるわけではありません。すべてのNVMeコマンドがSQとCQにアクセスする必要があるため、それらのアドレスがヒットレートに大きく影響します
データ固定と削除アルゴリズムのモデリング
特別なデータ固定(送信キューと完了キュー)とデータ置換に関するさまざまなアルゴリズムの影響をモデル化することもできます。その結果は次の2つの図をご覧ください。
最初のグラフは、行のサイズとSTUのサイズに対するキャッシュの依存性と、SQとCQをATCに固定した際の違いの有無について検証しています。比較的小さなキャッシュの場合、明確に違いがあります。2つの曲線は非常に似た形をしていますが、SQ/CQキャッシュの曲線を見るとキャッシュが小さくなるとヒットレートが大幅に高くなります。たとえば、STU = 2MBでキャッシュが1行の場合(実際にはほとんど起こりませんが、要点を把握しやすくするため)、SC/CQキャッシュがない場合のヒットレートは10%未満ですが、SQ/CQの固定がある場合は約70%になります。そのため、この取り組みを採用する価値があります。
選択した削除アルゴリズムに対するキャッシュの影響度については、Least Recently Used(LRU)、ラウンドロビン(RR)、純粋なランダム(Rand)をテストしました。以下のとおり、影響はほとんどありません。そのため、単純で効率性が最も高いアルゴリズムを選択する必要があります。
アルゴリズムの依存性:
- 使用ベンチマーク:
- YCSB WL BとCassandra
- 一部の構成要素
- アソシエイティビティ:フル・4ウェイ
- 削除アルゴリズム:LRU、Rand、ラウンドロビン
- 結果:
- 置換アルゴリズムによって目に見える違いは生じません
- 最も単純な実装を選ぶことが最も効果的なアプローチだと思われます
まとめ
結局のところ、これで何が可能になるのでしょうか? このアプローチで埋めるべきギャップは何でしょうか?
パフォーマンスと設計の影響を適切に調整できるよう、測定パラメータに関するATCキャッシュを定量的に設計する方法となることが分かりました。
このアプローチに関する注意事項:このレポートは私たちが行った初期分析を伝えるもので、最終的なものではありません。たとえば、ATS/ATCから最大のメリットを得られるのは仮想環境のアプリケーションですが、トレースはそのような環境で得られたものではありません。データからこのギャップの埋め方を知ることができますが、このアプローチは実践的なものではなく原理的なものです。すべてのASIC設計で適切なトレードオフを検討する必要があります。埋めるべきギャップはもう1つあります。ASICの設計には3年近くかかりますが、それを新製品で使用できるのはさらに2~3年で、現場で使用できるのも同様の年数ということです。3~7年後のワークロードがどうなっているかを予測するのは困難です。いくつのVMが何個のコアで動作し、どれだけのメモリを使用するでしょうか?
私たちのテストにより、定量的なソリューションを実現する道筋が見えました。未知のことは恐ろしく見えるかもしれませんが、モデリングの世界では珍しいことではなく、それに応じて新しいASIC設計でそれに対処する必要があります。