DMAとプログラムI/Oの違い:データ転送の方法を比較

デバイスとメモリの間でデータを動かす方法は2つあります。プログラムI/O(PIO)では、CPU自身が、レジスタを通して1ワードずつ読み書きします。ダイレクトメモリアクセス(DMA)では、DMAコントローラが自分でデータを動かし、CPUは転送の準備をするだけで、終わると通知を受けます。DMAは、CPUを解放し、大きな転送ははるかに速く行えますが、準備に手間がかかり、注意も必要です。

項目プログラムI/O(PIO)DMA
データを動かす主体CPU。ロードとストアの命令で1ワードずつDMAコントローラ、またはデバイス自身。メモリへ直接、またはメモリから直接
CPUの負荷高い。転送の間ずっと、CPUがふさがる低い。CPUは転送の準備をして、ほかの仕事をする
大きな転送のスループットCPUの速度に制限される高い
準備のオーバーヘッドなしアドレス、長さ、ディスクリプタの設定と、完了の処理が必要
小さな転送準備がないので、速いことが多い準備のコストが、利点を上回ることがある
複雑さ単純複雑。ディスクリプタのリング、バッファのアラインメント、キャッシュコヒーレンシ、IOMMUの設定
メモリバスの使用CPUを通るDMAのエンジンが、CPUとメモリの帯域を取り合う
主な用途小さな制御用のレジスタ、単純なセンサー、古いPIOモードSSDやNVMe、ネットワークカード、オーディオのバッファ、ADCのサンプルの連続した転送、GPUへの転送

数値は代表的な目安で、世代や製品によって異なります。

どんなときに使うか

PIO
転送が非常に小さいか、まれで、CPUの時間よりも単純さが重要なとき。
DMA
転送が大きいか連続していて、CPUをふさぎたくないとき。ストレージ、ネットワーク、ストリーミングデータなど。
注意
DMAでは、デバイスが読む前、または書いたあとに、CPUのキャッシュとメモリが一致していることを確認します(キャッシュのフラッシュや無効化をするか、コヒーレントなメモリを使います)。

よくある質問

なぜDMAはCPUの負荷を減らせるのですか?

DMAコントローラがデータを自分で動かすので、CPUは転送の準備をするだけで、終わると通知を受けるからです。

DMAはいつも速いですか?

いいえ。非常に小さな転送では、準備のコストが利点を上回り、プログラムI/Oのほうが速いことがあります。

DMAのディスクリプタのリングとは何ですか?

メモリ上にある、バッファを1つずつ説明するディスクリプタのリングです。ネットワークカードやNVMeのドライブのように、デバイスとドライバが、これを通してバッファをやり取りします。

なぜDMAではキャッシュコヒーレンシが重要なのですか?

デバイスがメモリを直接読み書きするので、CPUのキャッシュに古いデータが残ることがあります。ソフトウェアが、キャッシュのフラッシュや無効化をするか、コヒーレントなメモリを使う必要があります。

理解度チェック

ネットワークカードやNVMeのSSDなどで広く使われる、メモリ上の記述子(ディスクリプタ)の輪(リング)を使ったDMAのしくみについて正しいものはどれか。

  1. ACPUがデータを1バイトずつ機器のレジスタに書き込んで転送する
  2. BCPUは転送の番地や長さを記述子に書いて機器に知らせるだけで、機器が記述子を読んで自分で転送を進める
  3. C記述子は機器の中にだけあり、CPUからは見えない
答えと解説を見る

正解:B. CPUは転送の番地や長さを記述子に書いて機器に知らせるだけで、機器が記述子を読んで自分で転送を進める

記述子のリングは、メインメモリ上に並べた「どの番地から何バイト送るか」を書いた表を輪のように使うしくみです。CPUは空いている記述子に転送の内容を書き、機器のレジスタに「ここまで書いた」と1回知らせます。機器はDMAで記述子を読み、データを転送し、終わった記述子に完了の印を付けます。CPUと機器が互いを待たずに多くの転送を進められます。

マイコンでADコンバータの変換結果を一定の間隔で大量に取り込むとき、DMAを使う利点として正しいものはどれか。

  1. AADコンバータの分解能が自動で上がる
  2. B入力の電圧が自動で大きくなる
  3. C変換が終わるたびにCPUが割り込みで読む必要がなく、DMAがメモリに並べてくれるので、CPUの負担が減る
答えと解説を見る

正解:C. 変換が終わるたびにCPUが割り込みで読む必要がなく、DMAがメモリに並べてくれるので、CPUの負担が減る

変換のたびに割り込みでCPUが結果を読むと、1秒に数万回の取り込みでは割り込みの手間だけでCPUの多くの時間が使われます。DMAを使えば、変換が終わるたびにDMAが結果をメモリの配列に順に書き込み、配列がいっぱいになったときだけCPUに知らせます。タイマで変換を始める設定と組み合わせれば、正確な間隔での取り込みをCPUなしで続けられます。

キャッシュの一貫性をハードウェアが保たない(非コヒーレントな)システムで、装置がDMAで主記憶に書き込んだデータをCPUが読む前に、ソフトウェアが行う必要のある処理はどれか。

  1. ACPUのクロック周波数を一時的に下げる
  2. B該当する範囲のキャッシュの内容を無効にして、主記憶から読み直すようにする
  3. Cキャッシュの内容をすべて主記憶に書き戻してから、DMAで届いた結果を破棄する
答えと解説を見る

正解:B. 該当する範囲のキャッシュの内容を無効にして、主記憶から読み直すようにする

DMAはCPUを通さずに装置と主記憶の間でデータを転送するため、ハードウェアが一貫性を保たないシステムでは、CPUのキャッシュにはその範囲の古いデータが残っていることがあります。そのまま読むと、DMAで届いた新しいデータではなく古い値を読んでしまいます。そこでドライバは、読む前にその範囲のキャッシュを無効にして、主記憶から新しい値を読ませます。逆に装置に送るデータは、DMAを始める前にキャッシュから書き戻しておきます。

  1. IOMMUの主な役割として正しいものはどれか。

インターフェース・バス規格の練習問題へ

関連する用語の解説

DMA(ダイレクトメモリアクセス)
CPUを介さずに、周辺装置とメモリの間で直接データを転送する仕組み。大量のデータ転送の間もCPUが別の処理を進められる。
割り込み
外部機器からの要求などに応じて、実行中の処理を一時的に中断し、対応する処理を優先して行うCPUの仕組み。終わると元の処理に戻る。

関連する比較