Unter Direct Memory Access (DMA, deutsch selten Speicherdirektzugriff) versteht man, wenn Computer-Komponenten selbstständig ohne Beteiligung der CPU Daten übertragen können. Diese Technik erlaubt angeschlossenen Peripheriegeräten, wie z. B. Netzwerkkarte oder Soundkarte, ohne Umweg über die CPU direkt mit dem Arbeitsspeicher zu kommunizieren. Der Vorteil des DMA ist die schnellere Datenübertragung bei gleichzeitiger Entlastung des Prozessors.
Anders als der Name vermuten lässt, ist die wesentliche Eigenschaft von Direct Memory Access nicht der Speicherzugriff, sondern dass der Datentransfer von einem Peripheriegerät und nicht von der CPU selbst initiiert wird. Dabei braucht es zu keinen Speicherzugriffen zu kommen, es sind auch direkte Kommunikationen zwischen Peripheriegeräten möglich.[1][2]
Unter Remote Direct Memory Access versteht man den Zugriff auf Hauptspeicher entfernter Rechner über Netzwerkverbindungen, ohne dass das Betriebssystem bei diesen Transfers direkt involviert ist. Üblich ist dies bei Hochgeschwindigkeitsnetzverbindungen ab 100 GBit/s, wie z. B. 100 Gigabit-Ethernet oder InfiniBand. Dabei sind heutzutage bei weniger als 2 % zusätzlicher CPU-Last Speicherzugriffe auf entfernte Rechner mit 10–25 GByte/s und mit Latenzen von 500–1000 ns möglich.
Die ursprüngliche Methode, Daten von einer Eingabe-Ausgabe-Einheit in den Arbeitsspeicher zu transferieren, nutzt die CPU für die Datenübertragung[3].
DMA ist ein Feature, das es Peripheriegeräten erlaubt, unter Umgehung der CPU zu kommunizieren. Der Ablauf dabei[4] ist folgender
Die CPU des PC hat nur ein Paar BusRequest/BusGrant-Leitungen (HOLD/HLDA), die über einen Intel 8237 angesprochen werden. Dieser erlaubt bis zu vier DMA-Geräte zu betreuen (DREQ0–3, DACK0–3). Der IBM-PC/XT hat vier 8-bit-DMA-Kanäle (0–3), der IBM-PC/AT hat vier 8-bit-DMA-Kanäle (0–3) und vier 16-bit-DMA-Kanäle (4–7). Auf dem IBM-XT-Bus sind die DMA-Request/Acknowledge-Leitungen für drei 8-bit-Kanäle (1–3), auf dem IBM-AT-Bus sind zusätzlich die Leitungen für die Kanäle 0 und 4–7 verfügbar.
Auf ganz alten Motherboards kamen separate DMA-Bausteine wie zum Beispiel der 8237 oder der 8257 von Intel zum Einsatz. Mit dem Aufkommen von Chipsätzen Anfang der 1990er Jahre wurde ehemals diskrete Bauteile des IBM-PCs in diesen Chipsätzen integriert. Mit dem Aufkommen von Busmaster-DMA Ende der 1990er Jahre waren keine DMA-Funktionalität mehr notwendig, die Funktionalität übernehmen die Peripheriegeräte selbst.
Will die I/O-Hardware Daten senden oder empfangen, trennt der DMA-Controller den Prozessor vom Bussystem. Der DMA-Controller führt dann die Anforderung mit hoher Geschwindigkeit aus. Danach wird die Verbindung zwischen Prozessor und Bussystem wiederhergestellt. Für den Speichertransfer benötigt der Prozessor bis zu 40 Takte je Byte. Der DMA-Controller führt den Zugriff innerhalb von vier Takten aus.
Der DMA-Controller dient zum Datentransport zwischen Arbeitsspeicher und Peripherie. Dies führt zu einer Entlastung des Prozessors. Neben einem Geschwindigkeitszuwachs bei speicherintensiven Anwendungen ermöglicht die Verwendung von DMA-Controllern außerdem sehr hohe Datenraten z. B. beim Brennen von DVD-Medien. Selbst mit aktuellen PC-Systemen sind Brenngeschwindigkeiten von 16× ohne DMA-Unterstützung nicht möglich.
Der DMA-Controller muss die Daten zwangsläufig über dieselben Daten-, Adress- und Steuerleitungen des jeweiligen Bussystems übertragen (lassen) wie sonst die CPU. Es muss also dafür gesorgt werden, dass CPU und DMA-Controller nicht kollidieren. Dazu wird im Voraus eine „Arbitrierung“ durchgeführt, ein Verfahren, bei dem der DMA-Controller die Kontrolle über die Busse bei der CPU anfordert, letztere dies bei nächster Gelegenheit gewährt und dann die Busse freigibt. Nach Abschluss des DMA-Transfers wird die Busanforderung wieder zurückgenommen, und die CPU kann wieder übernehmen.
Elektronisch gibt es dazu verschiedene Implementierungen, mit verschiedenen Anzahlen von Steuerleitungen. Die einfachste Variante verfügt über eine Bus-Request-Leitung (Anforderung) vom DMA-Controller zur CPU sowie eine Bus-Grant-Leitung (Gewährung) in umgekehrter Richtung.
Man unterscheidet zwei verschiedene Adressierungsverfahren. Beim so genannten Explicit Addressing (auch Two Cycle Transfer) holt der DMA-Controller zunächst ein Datenwort (oder auch -byte) ab und speichert dieses in einem internen Register (wie eine CPU). Danach adressiert er die Zielkomponente und überträgt ihr die Daten. Für dieses Vorgehen werden also zwei Buszyklen benötigt. – Beim Implicit Addressing (oder Single Bus Transfer) entfällt die Zwischenspeicherung in einem Register: Der DMA-Controller adressiert das zu holende Datenwort und stellt dieses sofort zum Zielbaustein durch. Es wird nur ein einziger Buszyklus benötigt. Dieses Verfahren ist nicht für Speicher-zu-Speicher-Übertragungen geeignet, da jeweils nur eine Adresse am Speicher anliegen kann.
Effizient wird das DMA-Verfahren allerdings erst, wenn nicht nur ein einzelnes Datenwort zu übertragen ist, sondern größere zusammenhängende Speicherbereiche, z. B. ganze Datensektoren oder -spuren von einer Festplatte. Dann lohnt sich auch der gewisse Overhead, der dadurch entsteht, dass zuallererst der DMA-Controller durch Setzen diverser Registerinhalte für die bevorstehende Aufgabe aufgesetzt werden muss.
Die klassische DMA-Technik des ISA-Busses basiert dabei auf der Signalisierung der Peripherie für Transferbedarf durch einzelne Datenleitungen, die so genannten DMA-Kanäle. Wird nun solch ein Kanal angesteuert, so liefern Schaltkreise, die der Bus-Steuerung zugehörig sind, Adressen auf den Bus, die je Zyklus inkrementiert oder konstant gehalten sein können, während der initiierende periphere Schaltkreis entweder die aufgeschalteten Daten entgegennimmt oder aber selbst Daten auf den Bus aufschaltet. Da ein DMA die normale Bus-Tätigkeit unterbricht, ist eine Operation mit der CPU in diesem Zeitraum nicht möglich. Da es mehrere DMA-Initiatoren gibt, muss mit entsprechenden Prioritätsschemata gearbeitet werden. Weiterhin muss ein DMA-Kanal zunächst initialisiert werden und die Beschaltung des Busses mit Adress- und Steuersignalen muss ebenso erst per Software vorgegeben werden. Nach erfolgreichem Transfer wird meist ein Interrupt ausgelöst, der der System-Software mitteilt, dass der Vorgang abgeschlossen ist. Daraufhin werden die DMA-Schaltkreise meist so umprogrammiert, dass sie auf den nächsten zu bearbeitenden Datenblock verweisen.
Als DMA-Controller im weiteren Sinne muss jeder Baustein verstanden werden, der einen Speicherzugriff (entweder auf den Hauptspeicher selbst oder auf eine Peripheriekomponente) durchführen kann, ohne dabei die CPU in Anspruch zu nehmen. Dieses Grundprinzip kann jedoch vielfach variiert werden. So gibt es etwa Systeme mit einem zentralen DMA-Coprozessor, aber auch Systeme, in denen jede Komponente über einen eigenen, dezentralen DMA-Controller verfügt. Das letztere Verfahren unterscheidet sich von der Verwendung eines zentralen Controllers dadurch, dass keine DMA-Kanäle existieren. Vielmehr reserviert der anfordernde Schaltkreis den Bus für sich und adressiert diesen auch selbst. Jede Komponente, wie Prozessor oder periphere Bauteile können dabei der Initiator sein, der die Befehlsmacht über den Hauptspeicher (Adressierung, Datentransfer und Bussteuersignale) übernimmt. Der Busmaster überträgt nun seinem Ziel, dem Target, die für ihn vorgesehenen Daten. Zu einem bestimmten Zeitpunkt kann prinzipiell immer nur eine Komponente Busmaster sein.
INIR
und OTIT
beim Z80 und REP INS
und REP OUTS
beim 8086 möglich Daten unter Umgehung von CPU-Daten-Registern zu übertragen.