技術コラム集

ビリーへの質問(DMAとキャッシュの関係)

やぁみんな、ビリーだよ。

今日は、ビリー宛てにもらった質問を紹介しよう。

読者からの質問

ビリーさん突然すみません。

PCIデバイスにおけるDMA転送について調べていて、
ビリーさんの「キャッシュは諸刃の剣(2)」のページへたどり着いたところです。
CPUのキャッシュ機能の有無がDMA転送速度に影響する場合、
転送を行う設定をしているソフトウェアに原因があると考えて良さそうでしょうか。
実際の動きとして、キャッシュ機能を無効にするとDMA転送が遅くなるという現象が出ています。

大変お手数ですがよろしくお願い致します。


丁寧なメールどうもありがとう。こんな疑問ってみんなもあるかな? 
質問者の方に快諾いただいたので、今日はこのページで、この質問への回答をしてみよう。

DMA 転送の方式は CPU や DMA コントローラによって違うので、以下の回答はあくまでも一般的な場合、
として読んでね。

ビリーからの回答

PCI デバイスで DMA 転送、ということだけど、キャッシュを有効にしているかどうかで転送レートが変化する、
ということは起こりえるんだ。

転送を行う設定をしているソフトウェアに原因があるケースはごく限られていて、
どちらかというとキャッシュの設定(有効でよい箇所まで無効にしてしまう)の影響のほうが
大きいのではないかと思うんだ。
キャッシュの有効・無効を切り替えると以下のような影響がある。

(1) CPU のキャッシュ機能自体をすべて無効にする場合

この場合は、DMA 転送に限らずすべてのプログラムの動作のパフォーマンスに影響が出ることになるよね。

特に DMA 転送のプログラムでは、同じコードをループしながら繰り返し実行するといったケースが多いので、
本来ならキャッシュの効果が出やすいんだけど、キャッシュが無効だとその効果が得られないことになるね。
この場合は、DMA 転送を行うソフトウェアが原因とはならないよね。


(2) CPU のキャッシュのうち、命令キャッシュ(インストラクションキャッシュ)機能自体を無効にする場合

基本的には(1)と同じことが言える。この場合も、DMA 転送を行うソフトウェアが原因とはならないよ。

ビリー講義「キャッシュは諸刃の剣(2)」や「DMA 対応と言われたら(5)」で、
DMA 転送を行う際にはキャッシュの使い方に気を付ける必要がある、と言ったけれど、
これはデータキャッシュについてのことで、命令キャッシュについては禁止する必要はないんだ。


(3) CPU のキャッシュのうちデータキャッシュ機能自体を無効にする場合

この場合は、DMA 転送の他に、ある程度以上のサイズの配列や構造体にアクセスするようなプログラムにおいて、
パフォーマンスに影響が出ることになる。

DMA 転送バッファ自体はキャッシュ禁止にしておかなくてはいけないけれど、
DMA バッファにデータをコピーする元データがある場合、その元データの領域はキャッシュ有効にしておくべきで、
これが無効になっているとパフォーマンスが落ちてしまうことになる。
ただ、この場合も設定の問題であって、DMA 転送を行うソフトウェアが原因となる可能性は低いよ。


(4) DMA バッファとして使用する領域のみキャッシュ禁止にしている場合

DMA 転送の場合では、DMA 転送バッファ自体はデータキャッシュ禁止、
あるいはデータキャッシュは有効にした上で、
ドライバでキャッシュの Flush やInvalidate を行う必要があることは前に説明した通り。

これらの設定・コーディングが適切であれば、
DMA 転送を行うソフトウェアが原因となる可能性は低い(パフォーマンスはほぼ変わらないはずだよ)。
ただ、(4)の設定にもかかわらず、キャッシュの設定で転送パフォーマンスが変わる場合は、
不必要な Flush や Invalidate が入っていてパフォーマンスが低下する可能性は考えられるね。

以上をまとめると、

  • 命令キャッシュは有効にしておく。
  • データキャッシュは、CPU のレベルで全体を無効にするのではなく、
    DMA バッファとして使用する領域のみを無効にする。
    または DMA バッファをキャッシュ有効としたうえで、
    ソフトウェアでFlush や Invalidate といったコントロールを適切に行う。

とするのが、最も DMA 転送のパフォーマンスが上がる方法だと思うよ。
みんなも参考にしてね。


ビリーも聞かれて初めて気づくこともあるから、
この下にある、投票ボタンやビリーへの質問ボタンはどんどん活用してね。

拾八の巻:フラグメンテーション

ビリーの講義一覧

このページの上へ