# Multi-Line Prefetch Covert Channel with Huge Pages
## 3 Background  
### The Software Prefetcher  
A software prefetcher is a mechanism that allows a program to explicitly request the fetching of data from memory into the cache before it is accessed [17]. The purpose is to hide the memory latency by ensuring that data is already available in the cache when needed by the CPU. Software prefetching is typically initiated by inserting special prefetch instructions (e.g., PREFETCH in x86 or PLD in ARM) into the program code. These instructions act as hints to the processor that specific memory locations will likely be accessed soon, prompting the prefetcher to load the data into the appropriate cache level [18].  
The mechanism of software prefetching involves several steps. First, programmers or compilers strategically place prefetch instructions at points in the code where the memory access patterns are predictable, such as in loops that iterate over large datasets. For instance, in a loop processing an array, a prefetch instruction can be placed a few iterations ahead to ensure data is available when needed. Once executed, these instructions trigger the processor to fetch the specified memory location from main memory into the cache. On x86 architectures, instructions like PREFETCHW are used to prepare cache lines for future writes, while PREFETCHT0 brings data into the L1 cache. Similarly, ARM architectures utilize PLD for data prefetching and PLI for prefetching instructions. The fetched data is then stored in a specified cache level, such as L1, L2, or L3, depending on the type of prefetch instruction used. This operation is non-blocking, meaning it does not stall the CPU while waiting for the data to be fetched; the processor continues executing other instructions, allowing the prefetcher to asynchronously load the data into the cache [19].  
Software prefetching can handle both read and write operations. For example, the __builtin_prefetch instruction in x86 architectures is versatile and explicitly prepares cache lines for future writes by transitioning them to the modified state within the MESI protocol [20]. Prefetching does not alter the data itself; it merely ensures that the data is readily available in the cache for subsequent operations, thereby enhancing the efficiency without compromising data integrity.  
The advantages of software prefetching are significant. It reduces the memory latency by preloading data into the cache, thus minimizing delays when the data is accessed [21]. By ensuring frequently accessed data is present at the appropriate cache level, it improves cache utilization and reduces cache misses. This also minimizes pipeline stalls caused by memory access delays, leading to smoother instruction execution. Software prefetching is particularly effective in workloads with predictable access patterns, such as matrix operations prevalent in AI/ML applications, image processing, and large-scale numerical simulations [17]. By leveraging software prefetching effectively, programmers and compilers can achieve substantial performance gains in memory-intensive applications.  
In our baseline tests in Section 4.2, enabling software prefetching reduced the average memory access latency and provided a performance improvement of approximately 13%.