Direct Memory Access(ダイレクトメモリーアクセス、DMA)は、CPUを介さず、バスを使いメモリとメモリ、またはメモリとI/O(周辺デバイス等)の間で直接的にデータ転送を行う機能。

コンピュータにDMAが無い場合はデータ転送はCPUが行うが、DMAを使用している場合、CPUに代わりDMAがデータを転送する。DMAを制御する装置をDMAコントローラ(DMA Controller, DMAC)という。

## 概要

DMAを使うと高速のデータ転送が可能になり、コンピュータの性能を総合的に上げることができる。
DMAがあれば、CPUは、データ転送の仕事はDMACにまかせて、その時間をCPUにしかできない仕事に使うことができる。

ただし、DMAは1本しかないバスをCPUと分け合って使うため、バスの使用権の調整が必要となる。
このバスの使用権の調整は英語で「バスアービトレーション(Bus Arbitration)」といい、「バス権の調停」と訳されている。→#バスアービトレーション

DMAでのデータ転送は、通常は、DMACが行う。CPUはDMACに、データの転送元・転送先や転送モードやデータ数などを指定し、その後に転送開始のトリガーを送るだけである。トリガーを送れば、CPUは他のタスクを開始することができる。DMACの側は、データ転送の仕事を完了したら、CPUに割り込みをかけて転送終了を知らせる。またデータ転送でエラーが生じた場合も、CPUに割り込みをかけて知らせる。

なお、昔のISAバス方式では、CPUはマザーボードのチップセットに内蔵されたDMACに命令を送る方式であった。現代のPCIバスでは、「Bus mastering DMA」すなわちI/O機器の側がPCIバスの制御を任されDMA転送をすべて司る方式が採用されている。一方、組込システムでは、SoC内でバスに直結されたDMACがSoC内のバスを操作してDMAを実現するものがある。また、必要な転送性能や許容可能な消費電力等の使用条件に応じて複数のバスを使い分けることがあるが、この場合はDMACも各バスに対応したものを選ぶ必要がある。

ネットワークのパケット送信や音楽再生やビデオ配信などの際には継続的な読み出しを必要とし、DMAは専用の組み込みチップで使われている。またDMAは、マルチコアでもクラスタリングでも効果を発揮する。この場合、DMA通信の状態通知ピンとして、受信状態を示すHOLDピンと、送信状態を示すHLDAピンが存在する。

DMAの使用を前提とする場合、データバスのビット幅を必ずしもCPUのデータビット幅に合わせる必要はない。特に、データバスのビット幅をCPUのデータビット幅よりも広く取ることにより、CPU経由よりもさらに広帯域のデータ転送が可能となる。例として、AXIバスは2003年リリースの初版から最大1024ビット幅のデータバスをサポートしている。当時のCPUデータ幅は32ビットが主流であり、AXIバスとよく組み合わされているARMアーキテクチャにてAArch64が発表されるよりも8年前のことであった。

## バスアービトレーション

DMAのバスアービトレーションの方式の代表的なものとしては、ラウンドロビン、サイクルスチール、バーストがある。ラウンドロビンはバス権を順番に譲っていく方式。サイクルスチール方式では、CPUがメモリにアクセスしていないバスサイクルの間にDMAがバスを使う。バースト方式は、一定時間、1つのバスマスターがバス権を占有する方式で、優先度の高いデータを急いで転送したい時に使う。

## 使用上の注意

DMAの使用上の注意点として挙げられる主なもののひとつはオーバーランで、もう1つはキャッシュと併用するシステムのメモリの一貫性である。

オーバーランとは通信機能を使用する時など、受信バッファに取り込まれたデータをCPUやDMAが読み出さないうちに次のデータを取り込んでしまい、1つ前の受信データが失われてしまうこと。特にサイクルスチールやバースト方式では、CPUやDMAがバス使用権を待つ時間が長くなり、待つ間に通信機能が次のデータを受け取ってしまうとオーバーランが発生する。ラウンドロビン方式だと、バス使用権の待ち時間が短く、オーバーランは発生しにくい。

キャッシュを使ったシステムでは、キャッシュが持っているデータとキャッシュラインを共有するメインメモリをCPUとDMAのどちらか、ないしは両者が書き換えてしまうと、キャッシュとメインメモリのデータの一貫性が失われてしまうので、一貫性を管理する何らかの方法が必要となる。同じアドレスのメモリをCPUとDMAのいずれか、ないしは両者が更新してはならないことは自明だが、同一キャッシュライン上にDMA転送対象のメモリとそれ以外のメモリが混在している場合にも問題が発生することに注意を要する。

物理メモリアドレスをメモリのアドレッシングに用いる DMAC を使用して DMA を実行する場合、物理メモリのページ境界をまたがないようにする必要がある。境界をまたいだ場合、後続の論理アドレスページに対応する物理アドレスページが同様に連続した後続領域に確保されるとは限らないからである。DMAC がベクトルI/Oをサポートしている場合は、各物理アドレスページ毎に DMA 転送を設定し、それらを連続実行することにより物理メモリのページ境界をまたいだ DMA 転送が可能となる。

DMAC は一般に転送終了を CPU への割り込みにより通知するが、それとは別にデータ転送の端点となるデバイスが転送終了をデバイス独自の割り込みにより CPU へ通知できる場合がある。この場合、あるデータ転送において DMAC と端点デバイスの両者からほぼ同時に転送終了の割り込みが発生することや、いずれの割り込み処理にあっても同じデータへアクセスしなければならないことに起因する排他制御が必要となるため、CPU やソフトウェア上の負荷が増える。割り込みの負荷を軽減するには、DMAC ないしは端点デバイスのどちらかの割り込みを抑制する必要がある。これが実現できるかどうか、およびどちらの割り込みを抑制するのが良いかは、端点デバイスの仕様や DMA 転送の具体的な手順に依存する。

## 歴史

DMAはPDPシリーズにおいて採用されていた。

1970年代にリリースされた数MHzで動作するマイクロプロセッサでは、CPUによるデータ転送でハードディスク等の10MB/秒程度の転送速度を発揮する事は困難で、専用のコントローラでデータ転送を行う必要があった。このコントローラは、データ転送を高速に行う機能に特化したCPUであったともいえる。たとえばZ80にはZ80DMA、MC68000には、MC68450などのDMAコントローラ(DMAC)が用意されていた。

また、日立のH8にもDMACが存在している。

Intel 80286(APX286。1982年2月発表)などでは、当時通常のI/Oを制御するためには充分な動作速度だったことや、主流のパーソナルコンピュータにおいてi8249等の低速なDMACしか搭載されておらず、他に適当なDMACが存在しなかったことなどから、DMAはあまり使用されなくなった。

1990年代に、CPUの世代がPentiumになり充分に高速になると、今度は、低速なI/Oの管理がボトルネックとなったため、いわゆるチップセットにI/O専用の高速なDMACが搭載されたり、周辺機器制御LSIが簡単なDMA機能を持つようになり、再度DMAが活用されるようになった。Pentium以降主流となったPCIバスでは、バスマスタリングとしてDMAが実装されている。

初期のDMACは単純に指定されたアドレス範囲を指定されたメモリもしくはポートに入出力する機能のみを備えていた。しかしオペレーティングシステムが普及し、ハードディスクへのI/OにDMACを使う様になってから、DMACには「データブロックを分割する(スキャッタリング)」「データブロックを集約する(ギャザリング)」を行う機能が要求された。MC63450 DMAC等には、DMACがリンクリストを読み取って転送内容を分割したり集約する機能が搭載されている。PC/AT互換機向けのSCSIホストアダプタカード等では、コントローラチップに集積されているDMACがこの機能を担当していた。スキャッタリング・ギャザリング機能が無い場合CPUは最低でも1セクタ分ずつメモリ・メモリ間転送を行わなければならず、またDMACに読み取らせるメモリ領域が転送完了するまで使用できないため、I/O時のCPU負荷上昇とI/O待ち時間が発生しシステム性能に悪影響を与えた。

## DMAC、DMA機能を持つLSIおよびIP

代表的なものを挙げる。

- Z80DMA
- μPD8237AC-5(i8237A-5互換)
- MC68450
- i430など、PentiumCPU以降対応のチップセット
- μPD71037
- μPD71071
- CoreLink DMA-330 マイクロプログラムが必要で、その実装によりカスタマイズが可能。