Teorija
Tri tehnike U/I
Procesor ne upravlja uređajem izravno, nego preko I/O module (U/I modul) koji ima registar naredbe, registar podataka i status register (statusni registar). Stallings razlikuje tri tehnike prema dvama pitanjima: koristi li se prekid i ide li podatak u memoriju preko procesora ili izravno. Kod programmed I/O (programirani U/I) procesor izda naredbu i zatim u petlji čita statusni registar dok uređaj ne bude spreman: to je polling (prozivanje), oblik busy waiting (radno čekanje), pa za vrijeme prijenosa ne radi ništa korisno. Kod interrupt-driven I/O (U/I upravljan prekidima) procesor nakon naredbe radi drugi posao, a uređaj ga prekidom obavijesti da je riječ spremna. Kod direct memory access (DMA, izravan pristup memoriji) cijeli blok prenosi DMA modul, a procesor sudjeluje samo na početku i na kraju. U simulatoru s N = 4 riječi i D = 6 taktova po riječi programirani U/I troši svih 32 takta, INT 16 od 37, a DMA 4 od 29.
Three I/O techniques
The processor does not control a device directly but through an I/O module, which has a command register, a data register and a status register. Stallings tells the three techniques apart by two questions: is an interrupt used, and does the data go to memory through the processor or directly. With programmed I/O the processor issues a command and then reads the status register in a loop until the device is ready: this is polling, a form of busy waiting, so the processor does nothing useful during the transfer. With interrupt-driven I/O the processor does other work after the command, and the device tells it with an interrupt that the word is ready. With direct memory access (DMA) the DMA module transfers the whole block, and the processor takes part only at the start and at the end. In the simulator, with N = 4 words and D = 6 ticks per word, programmed I/O spends all 32 ticks, INT 16 of 37, and DMA 4 of 29.
Cijena prekida po riječi
Uz prekide procesor ne čeka uređaj, ali svaka riječ traži ulazak u interrupt service routine (ISR, rutina za obradu prekida): spremanje konteksta, prijenos riječi iz registra podataka u memoriju, naredbu za sljedeću riječ i povratak u prekinuti program. Taj trošak ne ovisi o brzini uređaja. Kod sporog uređaja (D = 20) prekidi se isplate, jer procesor 77 od 93 takta radi korisni posao; kod brzog uređaja (D = 1) INT završava tek u taktu 17, kasnije od programiranog U/I (takt 12), jer rutine traju dulje od samog čekanja. Kako procesor prihvaća prekid, sprema kontekst na stog i vraća se, prikazuje stranica Prekidi; što se u rutini događa na razini upravljačkog programa, stranica Upravljački programi.
The cost of an interrupt per word
With interrupts the processor does not wait for the device, but every word requires entering the interrupt service routine (ISR): saving the context, moving the word from the data register to memory, a command for the next word, and the return to the interrupted program. This cost does not depend on the speed of the device. With a slow device (D = 20) interrupts pay off, because the processor does useful work for 77 of 93 ticks; with a fast device (D = 1) INT finishes only at tick 17, later than programmed I/O (tick 12), because the routines take longer than the waiting itself. How the processor accepts an interrupt, saves the context on the stack and returns is shown on the Interrupts page; what happens in the routine at the level of the device driver, on the Device drivers page.
DMA i krađa ciklusa
Procesor u DMA modul upiše adresu u memoriji, brojač riječi i smjer prijenosa, a zatim nastavlja svoj posao. Kad uređaj pripremi riječ, DMA modul preuzme bus (sabirnica) na jedan ciklus i upiše riječ u memoriju. Procesor tada ne smije koristiti sabirnicu, pa čeka jedan ciklus: to je cycle stealing (krađa ciklusa). To nije prekid: procesor ne sprema kontekst, samo zastane. Kad brojač padne na nulu, DMA modul javlja jedan prekid za cijeli blok, pa procesor ISR izvodi jednom, a ne jednom po riječi. Ako procesor za vrijeme prijenosa radi iz priručne memorije i ne treba sabirnicu, ne čeka ni taj ciklus (prekidač „DMA zaustavlja CPU”). DMA modul može biti zaseban modul na sistemskoj sabirnici, spojen s U/I modulom ili vezan na zasebnu U/I sabirnicu; te konfiguracije razlikuju se po tome koliko puta riječ prelazi sistemsku sabirnicu. Isti prijenos bloka 24 s diska u scenariju „DMA prijenos bloka” dio je priče Put jednog poziva, a redoslijed zahtjeva disku određuje Raspoređivanje diska.
DMA and cycle stealing
The processor writes the memory address, the word count and the direction of the transfer to the DMA module, and then carries on with its own work. When the device has a word ready, the DMA module takes over the bus for one cycle and writes the word to memory. The processor may not use the bus then, so it waits one cycle: this is cycle stealing. It is not an interrupt: the processor does not save its context, it only pauses. When the count reaches zero, the DMA module raises one interrupt for the whole block, so the processor runs the ISR once, not once per word. If the processor works from its cache during the transfer and does not need the bus, it does not wait even for that cycle (the “DMA stalls the CPU” switch). The DMA module can be a separate module on the system bus, integrated with an I/O module, or attached to a separate I/O bus; these configurations differ in how many times a word crosses the system bus. The same transfer of block 24 from the disk in the “DMA block transfer” scenario is part of the Journey of a call page, and the order of the requests to the disk is shown on the Disk scheduling page.
Razvoj U/I funkcije
Stallings razvoj opisuje u koracima: najprije procesor izravno upravlja uređajem; zatim dolazi U/I modul, a procesor koristi programirani U/I; zatim isti modul s prekidima; zatim U/I modul dobiva izravan pristup memoriji preko DMA. U sljedećem koraku U/I modul postaje zaseban procesor sa skupom instrukcija za U/I, I/O channel (U/I kanal): središnji procesor mu u memoriji pripremi program i pokrene ga, a kanal javlja prekid tek kad izvede cijeli program. Na kraju modul dobiva i vlastitu memoriju, pa je to I/O processor (U/I procesor) koji sam upravlja velikim brojem uređaja. Svaki korak oslobađa procesor dijela posla oko U/I-a.
The evolution of the I/O function
Stallings describes the evolution in steps: first the processor controls the device directly; then comes the I/O module, and the processor uses programmed I/O; then the same module with interrupts; then the I/O module gets direct access to memory through DMA. In the next step the I/O module becomes a separate processor with an instruction set for I/O, an I/O channel: the central processor prepares a program for it in memory and starts it, and the channel raises an interrupt only when it has executed the whole program. Finally the module also gets its own memory, so it becomes an I/O processor that controls a large number of devices by itself. Each step relieves the processor of part of the I/O work.
Međuspremnici
Buffer (međuspremnik) je područje u memoriji operacijskog sustava u koje uređaj čita blok prije nego što ga proces zatraži: to je read ahead (čitanje unaprijed). Uz single buffer (jednostruki međuspremnik) uređaj čita sljedeći blok dok proces obrađuje trenutni, ali tek kad proces blok premjesti (M) iz međuspremnika sustava u svoj prostor. Uz double buffer (dvostruki međuspremnik) uređaj puni jedan međuspremnik dok proces prazni drugi. Circular buffer (kružni međuspremnik) ima k međuspremnika koji se pune redom. Za unos T i obradu C Stallings po bloku daje: bez međuspremnika T + C, jednostruki max(C, T) + M, dvostruki max(C, T). To je aproksimacija kad je M malen: u simulatoru proces sam premješta blok, pa je točno vrijeme po bloku za jednostruki M + max(T, C), a za dvostruki max(T, C + M). Kružni međuspremnik pomaže kad proces obrađuje u naletima: upija nalet, ali ne može biti brži od uređaja, pa je donja granica N · T + M + C zadnjeg bloka (u scenariju 12 · 4 + 1 + 13 = 62). Uređaj i proces ovdje su producer–consumer (proizvođač–potrošač) s bounded buffer (ograničeni međuspremnik), vidi Sinkronizacija.
Buffering
A buffer is an area in the operating system's memory into which the device reads a block before the process asks for it: this is read ahead. With a single buffer the device reads the next block while the process works on the current one, but only after the process has moved (M) the block from the system buffer into its own space. With a double buffer the device fills one buffer while the process empties the other. A circular buffer has k buffers that are filled in turn. For input T and compute C, Stallings gives the time per block: no buffer T + C, single max(C, T) + M, double max(C, T). This is an approximation for a small M: in the simulator the process moves the block itself, so the exact time per block is M + max(T, C) for the single buffer and max(T, C + M) for the double one. A circular buffer helps when the process computes in bursts: it absorbs the burst, but it cannot be faster than the device, so the lower bound is N · T + M + C of the last block (in the scenario 12 · 4 + 1 + 13 = 62). The device and the process here are a producer–consumer pair with a bounded buffer; see Synchronization.
Literatura: Stallings, Operating Systems: Internals and Design Principles, 9. izd., pogl. 11 (11.2 Organization of the I/O Function, 11.4 I/O Buffering) i pogl. 1 (1.7 Direct Memory Access); alternativno Tanenbaum & Bos, Modern Operating Systems, pogl. 5 (5.1.4 Direct Memory Access, 5.2.2–5.2.4 programirani U/I, U/I upravljan prekidima i U/I pomoću DMA, 5.3.3 međuspremnici).Reading: Stallings, Operating Systems: Internals and Design Principles, 9th ed., ch. 11 (11.2 Organization of the I/O Function, 11.4 I/O Buffering) and ch. 1 (1.7 Direct Memory Access); alternatively Tanenbaum & Bos, Modern Operating Systems, ch. 5 (5.1.4 Direct Memory Access, 5.2.2–5.2.4 programmed I/O, interrupt-driven I/O and I/O using DMA, 5.3.3 buffering).