DRAM (Dynamic RAM) is the cheap, high capacity memory that is practically ubiquitous in computer systems, including external memories on embedded systems (on-chip memories are often static RAM).
DRAM works by representing the presence of data bits as charge in a capacitor. The capacitor gradually discharges over time. Therefore, to prevent data loss, it is important to refresh the data. This is normally achieved by a DRAM controller that periodically reads then writes the value of every memory location.
Because a DRAM refresh involves a memory access, it can cause jitter (variations in time) to the execution of code. This happens when the DRAM controller and the processor both attempt to access the same parts of memory at the same time. The graph below [adapted from here] shows variations in execution time due to DRAM refresh. This represents the end-to-end execution time from a test application executed (using the same data) over a number of iterations – eliminating other sources of timing variability.
Timing variability caused by cache behaviour
In comparison to other causes of timing variability we have considered (parallelization, multicore, instruction caches, and pipelined architectures), DRAM refresh is a small, maybe even negligible effect (around 0.1% in the above example). However, if you need absolute accuracy in your timing measurements, DRAM refresh represents a problem.
Two approaches exist for making DRAM refresh more predictable (these are drawn from Bhat and Mueller’s paper “Making DRAM Refresh Predictable” [ http://moss.csc.ncsu.edu/~mueller/ftp/pub/mueller/papers/ecrts10.pdf ]):
- One possibility for making DRAM refresh predictable is to perform the refresh entirely using software: the DRAM controller is turned off and a low priority, periodic task forces a refresh by reading from each DRAM row (reading the row is sufficient to force a refresh to take place). This does require the period of the task to be sufficient to keep charge in the DRAM cells.
- Another possibility is to use a high priority, periodic interrupt controller to trigger the DRAM controller. The DRAM controller is configured to refresh the entire memory all at once. Once complete, the interrupt routine disables the DRAM controller until the next interrupt.
Either possibility eliminates jitter due to DRAM refresh from any application code and “boxes” the DRAM refresh overhead into a single periodic task/interrupt.