ダイレクトメモリアクセス(DMA)は、多くのコンピュータシステムの機能であり、特定のハードウェアサブシステムが中央処理装置(CPU)とは独立してメインシステムメモリにアクセスできるようにするものです。[ 1 ]
DMAを使用しない場合、データ転送にはプログラム入出力(PIO)を使用する必要があり、通常、転送中はCPUが完全に占有されるため、他の処理を実行できなくなります。DMAを使用すると、CPUはまず転送を開始し、転送中に他の処理を実行し、処理が完了するとダイレクトメモリアクセスコントローラ(DMAC )から割り込みを受け取ります。この機能は、CPUがデータ転送速度に追いつけない場合や、比較的低速なデータ転送を待っている間にCPUが処理を実行する必要がある場合に役立ちます。
ディスクドライブコントローラ、グラフィックカード、ネットワークカード、サウンドカード、そして(前述のデバイスタイプに代わって動作する)専用DMAコントローラなど、多くのハードウェアシステムがDMAを使用しています。DMAは、一部のマルチコアプロセッサにおけるチップ内データ転送にも使用されています。DMA機能を備えたコンピュータは、DMA機能を持たないコンピュータに比べて、はるかに少ないCPU負荷でデバイスとの間でデータを転送できます。
DMAはメモリ間転送にも使用できます。DMAは、大容量コピーやスキャッターギャザー操作などの高負荷なメモリ操作をCPUからDMAコントローラにオフロードできます。実装例としては、I/Oアクセラレーション技術が挙げられます。DMAは、ネットワークオンチップやインメモリコンピューティングアーキテクチャにおいて注目されています。
ハードウェアアクセラレーションは通常ベンダー固有ですが、クラスドライバによって直接メモリアクセスを使用できます。[ 2 ]

標準DMA(サードパーティDMAとも呼ばれる)はDMAコントローラを使用します。DMAコントローラはメモリアドレスを生成し、メモリの読み出しまたは書き込みサイクルを開始できます。DMAコントローラには、CPUによって書き込みおよび読み出し可能な複数のハードウェアレジスタが含まれています。これには、メモリアドレスレジスタ、カウントレジスタ、および1つ以上の制御レジスタが含まれます。DMAコントローラが提供する機能に応じて、これらの制御レジスタは、ソース、デスティネーション、転送方向(I/Oデバイスからの読み出しまたはI/Oデバイスへの書き込み)のいずれかの組み合わせを指定する場合があります。[ 3 ]
入力、出力、またはメモリ間操作を実行するために、ホストプロセッサは、転送するワード数と使用するメモリ アドレスをDMAコントローラに初期化します。次に、CPUは周辺機器にデータ転送を開始するよう指示します。DMAコントローラは、システムメモリへのアドレスと読み書き制御線を提供します。周辺機器とメモリ間でデータ 1 バイトを転送する準備が整うたびに、DMAコントローラは内部アドレス レジスタをインクリメントし、データ ブロック全体が転送されるまで続けます。
バスマスタリングシステム(ファーストパーティDMAシステムとも呼ばれる)では、CPUと周辺機器それぞれがメモリバスの制御権を持つことができます。周辺機器がバスマスタになれる場合、CPUの関与なしにシステムメモリに直接書き込み、必要に応じてメモリアドレスと制御信号を提供できます。バス競合が発生しないように、プロセッサをホールド状態にするための対策を講じる必要があります。周辺機器自体には、アドレスレジスタやカウントレジスタなどのハードウェアレジスタがあり、DMA動作を制御することができます。
バーストモードでは、データブロック全体が連続したシーケンスで転送されます。DMAコントローラはCPUからシステムバスへのアクセス権を取得すると、データブロック内のすべてのバイトを転送してからシステムバスの制御をCPUに返しますが、その間CPUは比較的長時間非アクティブ状態になります。このモードは「ブロック転送モード」とも呼ばれます。
サイクルスティールモードは、バースト転送モードに必要な時間の間CPUを無効化してはならないシステムで使用されます。サイクルスティールモードでは、DMAコントローラは、CPUとDMAコントローラ間のインターフェースを制御する2つの信号であるBR(バス要求)信号とBG(バス許可)信号を使用して、バーストモードと同じ方法でシステムバスにアクセスします。ただし、サイクルスティールモードでは、1単位のデータ転送後、BGを介してシステムバスの制御がCPUから解除されます。その後、データブロック全体が転送されるまで、BRを介して制御が継続的に要求され、要求ごとに1単位のデータが転送されます。[ 4 ]システムバスの制御を継続的に取得および解放することにより、DMAコントローラは実質的に命令転送とデータ転送をインターリーブします。CPUが命令を処理し、次にDMAコントローラが1つのデータ値を転送し、これを繰り返します。データ転送速度はバーストモードほど速くはありませんが、CPUがアイドル状態になる時間はバーストモードほど長くありません。サイクルスティールモードは、データをリアルタイムで監視するコントローラに役立ちます。
透過モードはデータブロックの転送に最も時間がかかりますが、システム全体のパフォーマンスという点では最も効率的なモードです。透過モードでは、DMAコントローラはCPUがシステムバスを使用しない処理を実行している場合にのみデータを転送します。透過モードの主な利点は、CPUがプログラムの実行を停止することがなく、DMA転送に時間がかからないことです。一方、欠点は、CPUがシステムバスを使用していないタイミングをハードウェアが判断する必要があり、これが複雑になる場合があることです。これは「隠蔽DMAデータ転送モード」とも呼ばれます。
![]()
DMAはキャッシュの一貫性の問題を引き起こす可能性があります。キャッシュと、DMAを使用するデバイスが直接アクセスできる外部メモリを備えたCPUを想像してみてください。CPUがメモリ内の位置Xにアクセスすると、現在の値がキャッシュに格納されます。ライトバックキャッシュを前提とすると、Xに対する後続の操作は、キャッシュされたXのコピーを更新しますが、外部メモリ上のXのバージョンは更新しません。デバイスが次にXにアクセスしようとする前にキャッシュがメモリにフラッシュされない場合、デバイスは古いXの値を受け取ることになります。
同様に、デバイスがメモリに新しい値を書き込んだときに、キャッシュされたXのコピーが無効化されない場合、CPUは古いXの値に基づいて動作することになります。
この問題は、システム設計において2つの方法で対処できます。キャッシュコヒーレントシステムでは、バススヌーピングと呼ばれるハードウェア方式を採用し、外部からの書き込みをキャッシュコントローラに通知します。キャッシュコントローラは、 DMA書き込みの場合はキャッシュ無効化、DMA読み出しの場合はキャッシュフラッシュを実行します。一方、非コヒーレントシステムでは、この処理はソフトウェアに任されます。OSは、送信DMA転送を開始する前にキャッシュラインがフラッシュされ、受信DMA転送の影響を受けるメモリ範囲にアクセスする前にキャッシュが無効化されていることを確認する必要があります。また、その間、実行中のスレッドがそのメモリ範囲にアクセスしないようにする必要があります。後者の方式では、ほとんどのハードウェアで各キャッシュラインを個別に無効化するためのループが必要となるため、DMA操作に多少のオーバーヘッドが発生します。
ハイブリッド型も存在し、その場合、セカンダリL2キャッシュはコヒーレントである一方、L1キャッシュ(通常はCPU上)はソフトウェアによって管理される。
初代IBM PC(および後継機種のPC/XT)には、 4つのDMAチャネル(番号0~3)を提供できるIntel 8237 DMAコントローラが1つだけ搭載されていました。これらのDMAチャネルは8ビット転送を実行し(8237は8ビットデバイスであり、PCのi8088 CPU/バスアーキテクチャに最適に適合していたため)、最初の(i8086 /8088標準の)1メガバイトのRAMのみをアドレス指定でき、その範囲内の単一の64kBセグメントのみをアドレス指定できるという制限がありました(ただし、ソースチャネルとデスティネーションチャネルは異なるセグメントをアドレス指定できました)。さらに、8237はチャネル0と1を使用してのみメモリ間転送を実行できたため、コントローラは拡張バスI/Oデバイスとの間での転送にのみ使用できました。PC(およびXT)のチャネル0は動的メモリのリフレッシュ専用でした。このため、汎用的な「ブリッター」として使用することができず、結果として、CPUの一般的なPIO速度によって制限されるPCにおけるブロックメモリの移動は非常に遅くなった。
IBM PC/ATでは、拡張AT バス(より一般的には業界標準アーキテクチャ(ISA) として知られています) に 2 番目の 8237 DMA コントローラが追加され、3 つの追加チャネル (5 ~ 7、チャネル 4 は最初の 8237 へのカスケードとして使用されます) が提供されました。これは、XT のオリジナルの PC に対する拡張性によるリソースの競合によって強調された、非常に必要なチャネルです。ISA DMA の拡張された 24 ビット アドレス バス幅により、最大 16 MB の下位メモリにアクセスできます。[ 5 ]ページ レジスタも、80286 CPU の 16 MB メモリ アドレス空間全体をアドレス指定するように再配線されました。この2番目のコントローラは、I/Oデバイスがデータソースおよび/またはデータデスティネーションとして使用される場合に16ビット転送を実行できる方法で統合されています(実際にはメモリ間転送のデータのみを処理し、それ以外の場合は16ビットシステムの他の部分間のデータフローを制御するだけなので、自身のデータバス幅は比較的重要ではありません)。これにより、上位3つのチャネルを使用した場合のデータスループットが2倍になります。
互換性のために、下位 4 つの DMA チャネルは依然として 8 ビット転送のみに制限されていました。チャネル 0 が DRAM のリフレッシュを処理する必要がなくなったため、メモリ間転送は技術的には可能になりましたが、実際には、コントローラのスループットが CPU が達成できるスループットに比べて低かったため、その価値は限られていました (つまり、最低 6 MHz で動作する16 ビットの最適化された80286 と、4.77 MHz に固定された 8 ビットコントローラ )。どちらの場合も、64 kBセグメント境界の問題は残っており、16 ビット モードでも個々の転送はセグメントをまたぐことができませんでした (代わりに同じセグメントの先頭に「折り返して」いました)。ただし、実際には、これはパフォーマンスの問題というよりプログラミングの複雑さの問題でした。約 15 μsごとにバスを独占するために DRAM のリフレッシュ (どのように処理されるか) が継続的に必要だったため、大きな (高速だが割り込み不可能な) ブロック転送を使用できなかったためです。
これらのデバイスは、性能が劣っていたこと(5 MHz で最大 8 ビット転送能力が 1.6 MB / s であったが、PC / XTでは0.9 MB /sまで、 AT では ISA バスのオーバーヘッドやメモリのリフレッシュ中断などの干渉により 16 ビット転送で1.6 MB /sまでであった[ 1 ])と、オリジナルの PC の標準クロック 4.77 MHz よりも高速で動作する直接交換品をインストールできる速度グレードがなかったことから、1980 年代後半以降、事実上時代遅れとなっている。
特に、1985年に登場した80386プロセッサとその32ビット転送能力(ただし、80186以降のIntel CPUにおけるアドレス計算とブロックメモリ移動の効率が大幅に向上したため、16ビットバスの286および386SXによるPIO転送でも8237を容易に凌駕することができた)に加え、独自のはるかに高性能なDMAサブシステム(EISAで最大33 MB/s、MCAで40 MB /s、VLB/ PCIで通常13 MB/s)を備えたISAバスのさらなる進化(EISA)または代替(MCA、VLB、PCI)の開発により、元のDMAコントローラはパフォーマンス向上ツールというよりむしろ足かせのように見えました。それらは、後期のマシンに組み込まれたレガシーPCハードウェアをサポートするために必要な範囲でサポートされていました。
32ビット拡張バスが普及した後もISA DMAを使い続けた旧式ハードウェアとしては、Sound Blaster規格との完全なハードウェア互換性を維持する必要があったSound Blasterカードや、マザーボード上のSuper I/Oデバイスが挙げられます。Super I/Oデバイスには、フロッピーディスクコントローラ、 FIR(高速赤外線)モードを選択した場合のIrDA赤外線コントローラ、 ECPモードを選択した場合のIEEE 1284パラレルポートコントローラが内蔵されていることがよくありました。オリジナルの8237sや直接互換機がまだ使用されていた場合、システムの実際のアドレス空間や搭載メモリ量に関わらず、これらのデバイスとの間のデータ転送はメインRAMの最初の16MBに制限される可能性がありました。
各DMAチャネルには、16ビットのアドレスレジスタと16ビットのカウントレジスタが関連付けられています。データ転送を開始するには、デバイスドライバがDMAチャネルのアドレスレジスタとカウントレジスタ、およびデータ転送の方向(読み出しまたは書き込み)を設定します。次に、DMAハードウェアに転送を開始するように指示します。転送が完了すると、デバイスはCPUに割り込みをかけます。
スキャッターギャザーまたはベクタI/O DMAは、単一のDMAトランザクションで複数のメモリ領域との間でデータを転送することを可能にします。これは、複数の単純なDMA要求を連結することに相当します。その目的は、複数の入出力割り込みとデータコピー処理をCPUからオフロードすることです。
DRQはデータ要求、DACKはデータ承認を表します。これらの記号は、DMA機能を備えたコンピュータシステムのハードウェア回路図によく見られ、CPUとDMAコントローラ間の電子信号線を表しています。各DMAチャネルには、要求線と承認線がそれぞれ1本ずつあります。DMAを使用するデバイスは、割り当てられたDMAチャネルの両方の線を使用するように構成する必要があります。
16ビットISAはバスマスタリングを可能にした。[ 7 ]
標準ISA DMA割り当て:
PCIアーキテクチャはISAとは異なり、中央DMAコントローラを持ちません。代わりに、PCIデバイスはバスの制御(「バスマスターになる」)を要求し、システムメモリからの読み書きを要求できます。より正確には、PCIコンポーネントはPCIバスコントローラ(通常はPCIホストブリッジ、およびPCI-PCIブリッジ[ 8 ])にバスの所有権を要求します。複数のデバイスが同時にバスの所有権を要求した場合、一度に1つのバスマスターしか存在できないため、PCIバスコントローラが仲裁を行います。コンポーネントに所有権が付与されると、PCIバス上で通常の読み書きコマンドを発行し、PCIバスコントローラがそれを要求します。
例えば、Intel CoreベースのPCでは、サウスブリッジがDMIを使用してトランザクションをメモリコントローラ(CPUダイに統合されている)に転送し、メモリコントローラがそれをDDR操作に変換してメモリバスに送ります。結果として、PCI DMA転送にはかなりの数のステップが含まれますが、PCIデバイスまたはPCIバス自体が他のコンポーネントよりも桁違いに遅いため(デバイス帯域幅のリストを参照)、これはほとんど問題になりません。
A modern x86 CPU may use more than 4 GB of memory, either utilizing the native 64-bit mode of x86-64 CPU, or the Physical Address Extension (PAE), a 36-bit addressing mode. In such a case, a device using DMA with a 32-bit address bus is unable to address memory above the 4 GB line. The new Double Address Cycle (DAC) mechanism, if implemented on both the PCI bus and the device itself,[9] enables 64-bit DMA addressing. Otherwise, the operating system would need to work around the problem by either using costly double buffers (DOS/Windows nomenclature) also known as bounce buffers (FreeBSD/Linux), or it could use an IOMMU to provide address translation services if one is present.
As an example of DMA engine incorporated in a general-purpose CPU, some Intel Xeon chipsets include a DMA engine called I/O Acceleration Technology (I/OAT), which can offload memory copying from the main CPU, freeing it to do other work.[10] In 2006, Intel's Linux kernel developer Andrew Grover performed benchmarks using I/OAT to offload network traffic copies and found no more than 10% improvement in CPU utilization with receiving workloads.[11]
Further performance-oriented enhancements to the DMA mechanism have been introduced in Intel Xeon E5 processors with their Data Direct I/O (DDIO) feature, allowing the DMA "windows" to reside within CPU caches instead of system RAM. As a result, CPU caches are used as the primary source and destination for I/O, allowing network interface controllers (NICs) to DMA directly to the last-level cache (L3 cache) of local CPUs and avoid costly fetching of the I/O data from system RAM. As a result, DDIO reduces the overall I/O processing latency, allows processing of the I/O to be performed entirely in cache, prevents the available RAM bandwidth/latency from becoming a performance bottleneck, and may lower the power consumption by allowing RAM to remain longer in a low-powered state.[12][13][14][15]
システムオンチップや組み込みシステムでは、一般的なシステムバスインフラストラクチャは、 AMBA高性能バスのような複雑なオンチップバスです。AMBAは、マスターとスレーブという2種類のAHBコンポーネントを定義しています。スレーブインターフェースは、組み込みCPU(例えばARM )上で動作するソフトウェアが、デバイス内部のI/Oレジスタや(あまり一般的ではありませんが)ローカルメモリブロックに書き込み/読み出しを行うことができるプログラム可能なI/Oに似ています。マスターインターフェースは、CPUに大きな負荷をかけずに、システムメモリとの間でDMAトランザクションを実行するためにデバイスによって使用できます。
そのため、ネットワークコントローラなど、システムメモリとの間で大量のデータを転送する必要のある高帯域幅デバイスは、AHBへのインターフェースアダプタとして、マスタインターフェースとスレーブインターフェースの2つを備えることになります。これは、AHBのようなオンチップバスが、バスのトライステート化やバス上の任意のラインの方向の切り替えをサポートしていないためです。PCIと同様に、DMAがバスマスタリングを行うため、中央DMAコントローラは不要ですが、システム上に複数のマスタが存在する場合はアービタが必要になります。
デバイス内部には、通常、ソフトウェアによってプログラムされた複数の同時スキャッターギャザー操作を実行するためのマルチチャネルDMAエンジンが搭載されています。
マルチプロセッサシステムオンチップにおけるDMAの使用例として、IBM/ソニー/東芝のCellプロセッサは、 1つのパワープロセッサ要素(PPE)と8つのシナジープロセッサ要素(SPE)を含む9つの処理要素それぞれにDMAエンジンを搭載しています。SPEのロード/ストア命令は自身のローカルメモリのみを読み書きできるため、SPEは他のSPEのメインメモリおよびローカルメモリとの間でデータを転送するためにDMAに完全に依存しています。したがって、DMAはこのCPU内部のコア間のデータ転送の主要な手段として機能します(インテルのキャンセルされた汎用GPUであるLarrabeeのようなキャッシュコヒーレントCMPアーキテクチャとは対照的です)。
Cell の DMA は完全にキャッシュ コヒーレントです(ただし、DMA によって操作される SPE のローカル ストアは、標準的な意味でのグローバル コヒーレント キャッシュとしては機能しません)。読み出し (「get」) と書き込み (「put」) の両方で、DMA コマンドは最大 16 KB の単一のブロック領域、または 2 ~ 2048 個のブロックのリストを転送できます。DMA コマンドは、ローカル アドレスとリモート アドレスのペアを指定することによって発行されます。たとえば、SPE プログラムが put DMA コマンドを発行する場合、ソースとして自身のローカル メモリのアドレスを、ターゲットとして仮想メモリ アドレス (メイン メモリまたは別の SPE のローカル メモリを指す) をブロック サイズとともに指定します。実験によると、Cell の DMA の実効ピーク パフォーマンス (3 GHz、均一なトラフィックの場合) は毎秒 200 GB に達します。[ 16 ]
スクラッチパッドメモリとDMAを備えたプロセッサ(デジタル信号プロセッサやCellプロセッサなど)は、ダブルバッファリングまたはマルチバッファリングによって、ソフトウェアでDMAメモリ操作と処理をオーバーラップさせることでメリットを得られる場合があります。例えば、オンチップメモリを2つのバッファに分割し、プロセッサが一方のバッファ内のデータを処理している間に、DMAエンジンがもう一方のバッファ内のデータをロードおよびストアします。これにより、メモリへのアクセスパターンを予測可能にする必要があるという代償はあるものの、メモリの遅延を回避し、バースト転送を活用できます。