Bei langsamen zeichenorientierten Geräten wie Tastatur leidet die
Systemleistung unter dem Interrupt-Aufwand nicht merklich.
Blockorientierte Geräte liefern dagegen zusammenhängende Daten,
manchmal fast in der Größenordnung der Hauptspeichergeschwindigkeit.
Es bietet sich dann natürlich nicht an, bei jedem Byte einen Interrupt
auszulösen und durch den damit verbundenen Aufwand (Latenz) das System
lahmzulegen.
Üblicherweise landet ja ein Block (beim Lesen) zunächst im
Pufferspeicher des Controllers. Statt eines Interrupts pro Byte kann nun ein
Interrupt pro Block ausgelöst werden. Danach muß die CPU allerdings
(in einer Schleife) die Bytes (oder Worte) einzeln über
Controller-Register-Operationen lesen und in den Hauptspeicher schreiben:
Bereitschaft abwarten, gewünschte Nummer schreiben, Befehl schreiben,
Status schreiben, Status abwarten, Byte lesen, Byte in den Hauptspeicher
kopieren. (Analoges gilt für das Füllen des Puffers vor einem
Schreibvorgang.)
Statt diese zeitaufwendige Lösung einzusetzen, gestattet man den
Controllern den "direkten" Zugriff auf den Hauptspeicher (über den
kleinen Umweg über einen DMA-Controller-Baustein).
Üblicherweise wird dennoch zunächst der Controller-interne Puffer
gefüllt und dann per DMA in den Hauptspeicher kopiert. Das liegt daran,
daß der Hauptspeicher kurzzeitig nicht zugänglich sein könnte,
weil er von einem anderen Controller oder der CPU benutzt wird. Das physische
Gerät liefert aber ohne Unterbrechung Daten, von denen keines
verlorengehen darf. (Es gibt Mischlösungen, bei denen normalerweise direkt
per DMA geschrieben wird und nur bei Hauptspeicher-Engpässen gepuffert
wird.)
Eine interessante Folge des zweistufigen Lesens ist es, daß auf Platten
oft keine aufeinanderfolgenden Sektoren gelesen oder geschrieben werden
können. Daher erhalten die Blöcke eine andere logische Reihenfolge
gegenüber der physischen -- es werden Blöcke übersprungen. In der
Zeit, in der der Kopf über den übersprungenen Blöcken schwebt,
findet z.B. der DMA-Vorgang statt. Die Anzahl übersprungener Blöcke
heißt
Interleave-Faktor.
Bemerkung: Auf Betriebssystem-Seite (und in den I/O-Bibliotheken)
wird oft noch zusätzlich im Hauptspeicher gepuffert:
-
Der Benutzer fordert die Eingaben byteweise an (getchar), das
Gerät liefert Blöcke.
-
Unterschiedliche Geschwindigkeiten beim Transfer zwischen verschiedenen
Geräten können ausgeglichen werden.
Für die koordinierte DMA bei mehreren Geräten wird normalerweise ein
weiterer spezialisierter Baustein eingesetzt, ein
DMA-Controller.
Er stellt mehrere
"DMA-Kanäle" zur Verfügung. Einige
Geräte sind fest auf einen solchen Kanal eingestellt, andere können
per Software oder mit Jumpern konfiguriert werden.
Der typische ISA-DMA-Controller bei Intel-Rechnern stellt acht Kanäle zur
Verfügung. Er arbeitet mit 16-Bit-Adressen, so daß DMA nur in die
untersten 16 MByte möglich sind. In Linux-x86 erfährt man die
Belegung der Kanäle mit "cat /proc/dma", z.B.:
1: Sound Blaster8
2: floppy
5: Sound Blaster16