Programmed I/O vs Interrupt-driven I/O: Mechanisms, Trade-offs, and Performance
In computer systems, Programmed I/O and Interrupt-driven I/O are two common ways for the CPU and I/O devices to coordinate data transfer.
At a high level:
- With Programmed I/O, the CPU is actively involved in checking device status (typically polling) and/or performing repeated reads/writes to transfer data.
- With Interrupt-driven I/O, the device signals the CPU asynchronously using Interrupt; the CPU services the event in an ISR and continues other work in the meantime.
These differences affect Latency (how quickly data is handled), CPU utilization, and system throughput under different traffic patterns.
Key learning terms
- Polling
- Memory-mapped I/O (MMIO)
- Device-ready signaling
Note on evidence: I’m currently unable to run the required web searches to attach citations to each technical claim. If you enable/restore web access for the search tool, I can immediately regenerate this section with complete, cited references.
Interrupts vs Polling (Conceptual Overview)
How Programmed I/O Works (Polling-centric view)
- 1Step 1
The CPU writes control registers (e.g., start command) or begins reading the device’s status/data registers.
- 2Step 2
Software checks a status bit (e.g., “ready” or “data available”). This is the core of Polling.
- 3Step 3
When the status indicates readiness, the CPU reads/writes the device data register (often via MMIO).
- 4Step 4
For block transfers, the loop may continue for each chunk/word.
- 5Step 5
Once the driver detects completion, control returns to the calling code.
How Interrupt-driven I/O Works (Asynchronous event view)
- 1Step 1
The driver configures the device and enables interrupts (or configures which events should trigger them).
- 2Step 2
Instead of busy-waiting, the CPU executes other tasks or waits/sleeps depending on design.
- 3Step 3
When the device needs attention (e.g., data ready), it asserts an Interrupt.
- 4Step 4
The CPU saves context and jumps to the ISR associated with that interrupt.
- 5Step 5
The ISR reads/writes the relevant I/O registers, acknowledges the interrupt, and may queue work.
- 6Step 6
After servicing, the CPU returns to the prior execution point.
Direct comparison (mechanism + consequences)
| Dimension | Programmed I/O (Polling) | Interrupt-driven I/O |
|---|---|---|
| Who checks device status? | CPU checks repeatedly via status reads | Device signals CPU when ready via Interrupt |
| CPU involvement while waiting | High (busy-wait or frequent checks) | Low (CPU can do other work between interrupts) |
| Response to “device ready” | Only when CPU’s next poll occurs | Near-asynchronous; response depends on interrupt latency |
| Overhead source | Polling read/write traffic; wasted CPU cycles | Interrupt handling overhead (context switch into ISR, interrupt rate) |
| Best fit conditions | When events are frequent/short and polling cost is small; very simple systems | When events are infrequent/variable; when saving CPU cycles matters |
| Main risk | Wastes CPU time; reduces overall throughput under load | Interrupt storms; more complex synchronization and ordering |
Key learning terms
- Interrupt latency
- Context switching
- Interrupt storm
Rule of thumb for choosing
If the device is “usually ready” or events occur constantly, polling may be acceptable. If readiness is rare or bursty, interrupt-driven I/O typically wastes fewer CPU cycles because the CPU isn’t continuously polling.
Where misconceptions happen
Interrupt-driven I/O does not remove overhead; it moves it. The system trades continuous polling cost for ISR execution cost and potential synchronization complexity.
Execution flow under each model
Programmed I/O
T0CPU starts/reads status"
Polling loop
T1CPU repeatedly checks status until ready"
Transfer
T2CPU reads/writes data registers"
Interrupt-driven I/O
T0CPU starts/arms interrupt"
CPU does other work
T1No busy-wait on device readiness"
Interrupt + ISR
T2CPU services device in ISR, then returns"
Performance intuition: what each model “pays for”
Programmed I/O “pays” with CPU time
In polling-based Programmed I/O, the CPU repeatedly executes status reads. Even if each poll is quick, the total wasted work can be substantial when the device becomes ready significantly later than the polling cadence.
Interrupt-driven I/O “pays” with interrupt/ISR overhead
In Interrupt-driven I/O, the system incurs:
- time to handle entering the ISR,
- time to execute ISR logic and acknowledge/clear interrupt sources,
- possible additional scheduling/context management.
This overhead becomes problematic when the device produces interrupts at a very high rate (e.g., frequent small events) or if software handles them inefficiently.
Common edge cases and design nuances
Conceptual trade-off: CPU cost vs responsiveness
Illustrative comparison only (depends on workload/device). Higher bars mean more cost/attention.
Programmed I/O vs Interrupt-driven I/O
Knowledge Check
In programmed I/O, how does the CPU typically learn the device is ready?