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転送を実行でき、プログラマーに見えない余計なサイクル数を完全に排除できる。



Cellプログラミングのレシピに戻る

表示
個人用ツール
Open Source Projects