DMA転送のパフォーマンスを測る 3 PTE入れ替えの問題
出典: PS3 Linux Information Site / Cell/B.E.のパワーを体験しよう
目次 |
DMA転送の隠されたコストを知る
スループットとレイテンシーを知りアライメントを適切に設定してもまだ十分ではありません。 DMA転送にはもう一つ知らなければならない事があります。
Media:dma-perform-pte-1.tar.gz
まず下記の実験結果をご覧ください。これはごく単純に1024バイトずつ連続して16回DMA転送(get)を行なったときにかかったサイクル数です。
計測結果は
アドレス = サイクル数
の形で表示しています。
$ ./ppe.out Sarah: setup 1 spe threads Sarah: waiting all spe threads end... 0x10016000 = 146080 0x10016400 = 680 0x10016800 = 640 0x10016c00 = 640 0x10017000 = 134920 0x10017400 = 600 0x10017800 = 640 0x10017c00 = 640 0x10018000 = 120440 0x10018400 = 640 0x10018800 = 600 0x10018c00 = 760 0x10019000 = 118800 0x10019400 = 640 0x10019800 = 640 0x10019c00 = 640 Sarah: delete all spe threads main end
このように4Kバイトごとに2,3桁も多く時間がかかっている事がわかります。これはなぜでしょうか?
ページフォールト
実はこの4Kバイトというのはすぐにピンとくる数字です。Linuxはメモリ空間を扱うときに(典型的には)4Kバイトごとのページに分けて管理しています。このサイズは getconf PAGE_SIZE で取得できます。
$ getconf PAGE_SIZE 4096
PPE側のコードをよく見てみるとDMA転送で使われる buf には一切さわっていません。Linuxではデマンドページングと呼ばれる機能が実装されており、データに初めてアクセスしたときにページフォールトがかかりメモリが確保されます。従ってSPEが起動した時にはまだOSがメモリを確保していません。
おそらくSPEはここからDMA転送しようとするとページフォールトを起こしてPPE側に割り込みをかけてLinuxがメモリを確保するまでストールします。この結果4KバイトごとにDMA転送が非常に長い時間待たされるものと推測します。
PTEの入れ替え
Media:dma-perform-pte-2.tar.gz
さて遅い原因はページバウンダリを超えたことによるページ入れ替えのためにかかるコストだと推測されたので、あらかじめPPE側で buf を一回さわっておきます。
PPE側に2行追加します。
for (int i = 0; i < sizeof(buf); i++) buf[i] = i;
再び結果を測定します。
$ ./ppe.out Sarah: setup 1 spe threads Sarah: waiting all spe threads end... 0x10016000 = 1120 0x10016400 = 640 0x10016800 = 920 0x10016c00 = 640 0x10017000 = 1120 0x10017400 = 920 0x10017800 = 680 0x10017c00 = 680 0x10018000 = 1160 0x10018400 = 640 0x10018800 = 640 0x10018c00 = 640 0x10019000 = 1560 0x10019400 = 640 0x10019800 = 640 0x10019c00 = 680 Sarah: delete all spe threads main end
4Kバイトごとにかかっていた膨大な時間はなくなりました。しかしまだ4Kバイトごとに 500cycle ほど余計に時間がかかっています。これはなぜでしょうか?
実は 500cycle というのも覚えがある数字で一回のDMA転送のレイテンシーがこれぐらいです。 CBE Architecture の14章ストレージ・アドレッシングでは
2. 仮想アドレスを実アドレスに変換する。仮想アドレスから実アドレスへの変換にはメインストレージ内 のページ・テーブルが使用されます。
と書かれています。Cellはごく普通のページング方式をとっていると考えられ、初回のページアクセスはメインストレージ上に存在するページテーブルエントリーをMFCに転送する時間として 500cycle 必要なのだと思われます。
さらに続いてCBE Architectureでは
これらの変換の性能を強化するために、ほとんどのインプリメンテーションは変換ルックアサイド・バッ ファ(TLB)管理(196 ページ参照)を提供しています。TLB は基本的に、最近使用されたページ・テーブ ル・エントリ(PTE)を保持するための特別なキャッシュです
と書かれていて、2回目以降はキャッシュを使うためこの余計な時間は必要ないのだと推測しています。
(なお、PPEではTLBが1024エントリあるのに対し、SPEでは256エントリしかありません。 このため、ページフォルトが起こらない場合でも4K境界を越えるアクセスが 頻繁に起こるとTLBのスラッシングが起こり、ページテーブルアクセスのために 毎回オーバヘッドがかかることがあり得ます。この問題を回避する1つの方法は ページテーブルサイズを4Kより大きくすることです。)
まとめ
アライメントを適切に設定するのに加えてページテーブルエントリーに気を配ることで無駄のないDMA転送を実行でき、プログラマーに見えない余計なサイクル数を完全に排除できる。
