MOB (Buffer that orders memory operations)

MOB (Memory Order Buffer) is a hardware unit inside the processor that ensures reads and writes to memory, executed speculatively and out of order, become visible to the rest of the system in the correct sequence prescribed by the program, without slowing it down.

The MOB is an integral part of the instruction scheduler in high-performance microprocessors implementing out-of-order execution, such as Intel Xeon, AMD EPYC server chips, or Apple Silicon. The MOB architecture is critically important for the operation of load and store arithmetic logic units (LSUs). It functions in close coordination with the first-level cache, allowing the processor to handle multiple cache misses in parallel.

The main challenge lies in restarting execution from the correct point when a dependency violation is detected: if a speculative load executes before a store to the same address, all subsequent operations dependent on its incorrect result must be discarded and re-executed. The limited size of the MOB becomes a bottleneck during a flood of cache misses, blocking the issue of new instructions and reducing the overall throughput of the memory subsystem.

How the MOB works

Unlike the Reorder Buffer (ROB), which tracks instruction completion according to program order, the Memory Order Buffer purposefully resolves conflicts between loads and stores without rolling back entire chains of instructions. When a load instruction is issued for out-of-order execution, the MOB compares its address with the addresses of all older store instructions not yet written to the cache, waiting in the Store Queue. If the addresses match, memory bypassing occurs: the result is directly forwarded from the Store Queue to the load operation, bypassing the slow cache memory. If the store address has not yet been calculated at the time of the speculative load, the MOB records this unresolved relationship. When the actual store address is finally determined and points to the same memory location as the prematurely executed load, the MOB unit raises a gross ordering violation flag and triggers a pipeline flush of the erroneous instruction and all operations dependent on it, guaranteeing architectural data integrity.

MOB functionality

  1. Speculative execution of loads. The MOB allows loads to execute out of order and overtake older stores. Speculatively read data is temporarily placed in a physical register, but the result is considered invalid until all address conflicts with previous write operations are resolved.
  2. Predictive data forwarding. To minimize delays, the buffer implements a store-to-load data forwarding mechanism. If the address of a younger store matches the address of a new load, the data is forwarded directly from the store queue, bypassing the first-level cache.
  3. Memory disambiguation. The main task of the MOB is the dynamic detection of ordering violations between loads and stores. The logic checks whether a speculatively executed load read a stale value before an older store to an overlapping address completed its write to the cache.
  4. Store queue structure. The store queue holds the address, data, and validity status of each pending write. Entries are ordered strictly in program order. Data is held until the instruction is retired, blocking premature visibility of results to other cores.
  5. Load queue structure. Unlike the strict order of stores, the load queue tracks all speculatively executed reads. Each entry contains the physical address, the destination architectural register, and a flag signaling the need for a restart upon detecting a conflict with a woken store.
  6. Observation block atomicity. The MOB forms a barrier around a group of instructions to ensure the atomicity of memory transactions. While instructions are not ready for retirement, external invalidating snoops from other cores must not affect the speculative data state protected by the buffer.
  7. Store lifecycle stages. A store first reserves a slot in the buffer at the decode stage. Then, at the execution stage, the address is calculated and the data is entered into the queue. The physical write to the cache occurs strictly after the instruction retires, converting the speculative state into an architectural one.
  8. Pipeline restart protocol. Upon detecting a memory ordering violation, the MOB initiates a pipeline flush. The faulty load and all instructions dependent on it are evicted from the schedule, after which fetching resumes from the address of the incorrectly executed instruction.
  9. Dependency prediction filter. To reduce the number of flushes, the buffer uses a predictor that remembers the history of address collisions. If a pair of instructions previously caused a conflict, the scheduler forcibly serializes the execution of the load, waiting for the resolution of the dangerous store address.
  10. Interaction with the TLB. When generating a physical address, the MOB captures an instantaneous snapshot of the address translation block state. If a TLB flush or access rights change occurs after speculative reading, the entry in the load queue is marked as requiring virtual tag verification.
  11. TLB (Translation Lookaside Buffer)
  12. Global observation point. A store becomes globally visible only after retirement and exit from the store queue. The delay between retirement and commit to the cache allows the MOB to combine multiple writes into one cache line, optimizing the throughput of write ports to the memory subsystem.
  13. Snoop invalidation. Upon receiving a cache line flush request (snoop), the MOB logic checks for address overlap with active loads. If a speculative read consumed data that another thread is modifying, the buffer asserts a machine clear signal to eliminate the speculative information leak.
  14. Prefetching data. Some implementations use information from the store queue to initiate prefetching. Detecting a streaming write pattern, the MOB-based prefetcher initiates a request for exclusive ownership of the following cache lines even before the request address is actually computed.
  15. Unaligned access handling. When crossing a cache line boundary, the MOB splits one architectural instruction into two micro-operations. The buffer tracks both parts atomically, guaranteeing that an interrupt or fault at the block boundary does not leave memory in a partially updated state.
  16. Store queue compression. Under high load, the MOB scans the store queue to merge consecutive byte writes into one combined bus transaction. Merging allows more efficient use of data bus bandwidth, turning several partial write masks into a single burst request.
  17. Deferred store-to-load disassembly. Upon detecting an address match with masked bits, the MOB blocks early forwarding if the precision of the physical comparison does not guarantee a complete match of all bytes. Forwarding is delayed until the full address is calculated to prevent false forwarding.
  18. Instruction age fixation. Each entry in the MOB is assigned a monotonically increasing identifier corresponding to the order in the ROB. This timestamp is used by the arbiter during port conflicts: priority is given to the oldest load or store waiting for resolution for the greatest number of cycles.
  19. Tag virtualization. In systems with simultaneous multithreading, the buffer partitions the physical entry array but tags each entry with a hardware thread identifier. The forwarding logic strictly isolates data transfer, prohibiting the leakage of speculative stores from one thread into the load pipeline of another.
  20. Energy-efficient strobing. Since the MOB contains many address comparators triggering every cycle, banked clocking is applied. Groups of instructions predicted as independent are placed in disabled buffer sections, which reduces the dynamic power consumption of the verification unit without performance loss.

Comparisons

  • MOB vs Load Queue. The memory order buffer manages speculative reads at the execution stage, tracking their age and order to resolve conflicts with writes. The load queue is mainly responsible for storing addressed requests and dispatching them to the cache, lacking full-fledged logic for checking ordering violations or forcibly reordering speculative data.
  • MOB vs Store Buffer. The store buffer temporarily holds data and addresses of speculative writes until they are confirmed, providing data forwarding to reads. The MOB combines this buffering with the load queue into a unified structure, globally tracking the age of all memory operations for centralized detection of ordering violations and triggering recovery of the speculative processor state.
  • MOB vs Reorder Buffer. The global reorder buffer manages the sequential retirement of all instructions, preserving temporary results. The specialized MOB functions as its subordinate extension, applying the concept of age specifically to memory addresses and checking consistency, whereas the ROB cannot detect a write-after-read conflict requiring a comparison of physical addresses of different memory operations.
  • MOB vs Store Queue. The store queue holds only uncommitted store operations in program order. The MOB evolutionarily builds upon it, integrating both reads and writes for continuous monitoring of their mutual order. Unlike the isolated store queue, the MOB actively searches for cases where a later load speculatively read a value before an earlier store in the queue became visible, causing a pipeline flush.
  • MOB vs Memory Disambiguation Predictor. The hardware memory disambiguation predictor forecasts address conflicts, allowing speculative reordering of reads before writes without delays. The MOB implements the verification mechanism for these predictions: it tracks the executed reordering, comparing store and load addresses, and initiates a flush upon detecting a real dependency, operating as a speculative window verification circuit.

OS and driver support

The operating system interacts with the MOB not directly, but through memory management abstractions, where drivers configure mapped memory ranges (MMIO) and coherency flags during initialization; write barriers (SFENCE) in driver code guarantee that data from the buffer is flushed to the area visible to the device; and critical sections protect the MOB from race conditions during asynchronous hardware interrupts, while the OS scheduler must perform a full store buffer drain when migrating a thread to another core to comply with the architecture’s memory model.

Security and isolation

To prevent side-channel leaks, such as Spectre v4 (Store Bypass), hardware binding of speculative writes to the security context is implemented, where the MOB dispatcher compares protection domain identifiers before executing data forwarding; and the operating system applies synchronizing instructions (e.g., SSBD) upon entering kernel mode, flushing the buffer contents to invalidate speculatively computed states and depriving an attacker of the ability to measure access latency differences.

Hardware logging and tracing

The logging subsystem is implemented through built-in Performance Monitoring Units, which, without halting the core, capture store queue overflow events, cases of speculative store rollbacks, and the number of idle cycles waiting for a cache line to be freed, forming trace data packets (PTW) output externally via a dedicated debug port; these metrics allow the profiler to detect false sharing patterns at the level of individual physical addresses.

Limitations

A fundamental limitation of the MOB is the finite capacity of the load queue and store queue, which forces the processor to flush the pipeline when all buffer slots are filled with unresolved speculative writes; in addition, the ordering detector is unable to analyze address overlaps computed dynamically beyond the instruction window, so in case of uncertainty it engages a conservative replay mode for dependent loads, reducing execution throughput.

History of microarchitectural development

The evolution of the MOB began with a simple FIFO write combining buffer in Pentium processors, then in Core 2 Duo a speculative bypass algorithm with a dependency predictor was introduced to parallelize out-of-order access; and in modern high-performance cores (from Sandy Bridge to Golden Cove) the structure sizes have been increased to over two hundred entries and a two-level hierarchy with dedicated buffers for uncacheable requests has been implemented, minimizing blocking when processing I/O ports and interacting with DMA devices.