---
# System prepended metadata

title: 'P-OPT: Practical Optimal Cache Replacement for Graph Analytics Architectures'
tags: [Cache Replacement]

---

#  P-OPT: Practical Optimal Cache Replacement for Graph Analytics Architectures
###### tags: `Cache Replacement`
###### paper origin: ISCA-2021
###### papers: [link](https://users.ece.cmu.edu/~vigneshb/papers/hpca21.pdf)


# 1. Introduction


* Graph data reuse is dynamically variable and graph-structure-dependent, two properties not captured well by existing replacement policies. 

* The main contribution of this paper is a practical cache replacement policy which can approach Belady’s MIN replacement policy without using future knowledge **by directly referring to the graph’s structure** for replacement decisions.

## 1.1 Contribution

*  This paper show that state-of-the-art cache replacement policies are ineffective for graph processing 
* This paper show that guiding replacement based on graph structure in T-OPT allows emulating Belady’s MIN policy without oracular knowledge of all future accesses
* This paper describe P-OPT’s quantized Rereference Matrix data structure and architectural mechanisms that allow low-cost access to the graph transpose for optimal replacement.
* This paper evaluate P-OPT across a range of graphs and applications comparing to many state-of-the-art systems, showing P-OPT’s consistent performance benefits

# 2. Background

## 2.1  Overview of Graph Processing

### Data Structure
![](https://i.imgur.com/Um2dFgH.png)

* real-world graphs are often very sparse (>99% sparse). The Compressed Sparse Row/Column (CSR/CSC) format is storage efficient and can quickly identify a vertex’s neighbors
    * Offsets Array (OA : stores the starting offset of a vertex’s neighbors in the Neighbor Array (NA), Neighbor Array (NA) : stores each vertex’s neighbors.
    * To access the neighbor of vertex i, an application accesses the ith and (i+1)th entries in OA to find the range of indices in NA containing vertex i’s neighbors 
    * **CSR encodes outgoing destination neighbors** for each source vertex, **CSC encodes incoming source neighbors** for each destination vertex
    * Most frameworks store CSR and CSC because common algorithms  and optimizations require fast access to both outgoing and incoming neighbors

### Graph Traversal Pattern
![](https://i.imgur.com/RJPNwj8.png)

* A common idiom in graph processing is to iteratively visit each edge and update per-vertex data corresponding to the edge’s source and destination vertices.
    * Traversing **outgoing neighbors (using CSR)** is a **push** execution.
    * Traversing **incoming neighbors (using CSC)** is a **pull** execution
* Algorithm 1 shows a pull execution of a graph processing kernel  
* However, the **arbitrary order of the CSC’s Neighbor Array** leads to an irregular, graph-dependent pattern of accesses to srcData. Real-world graphs are very large (GBs – TBs), and **irregular accesses to large graphs have poor cache locality.**


## 2.2 Limitations of existing replacement policies

![](https://i.imgur.com/ivMrxnU.png)


* the characteristics of graph processing render state-of-the-art replacement policies ineffective
* Simple policies (LRU and DRRIP) **do not learn graph-structure-dependent irregular access patterns**
* SHiP-PC and Hawkeye use the PC to predict rereference, assuming all accesses by an instruction have the same reuse properties




# 3. TRANSPOSE-BASED OPTIMAL CACHE REPLACEMENT

## 3.1 Transpose Encodes Future Reference Information

++problem with OPT:++
* OPT implementation must scan the contents of NA to find when a particular source vertex will be referenced by destination vertex. 
    * for example, after first access to S1 pointed by D0, the OPT will scan the NA and find that S1 will be re-referenced by D4 again
* In the worst case, **the entire NA may be scanned** to find the next reference SrcData, which results in a complexity of  $O(|Edges|)$ 

++solution using the transpose:++

* By accessing the CSR, we can quickly learn that vertex S1 has two outgoing neighbors – vertex D0 and D4 – and, hence, srcData[S1] will only be accessed next while processing the incoming neighbors of vertex D4
    * the complexity of finding the next future reference of a srcData element is reduced to $O(|OutDegree|)$, i.e., scanning the outgoing neighbors of a vertex . 
* conversely, a push execution model using a CSR can also use its transpose (CSC) for estimation of next references to irregular dstData accesses.
![](https://i.imgur.com/x8xTNG4.png)

* Figure 3 (center panel) shows a 2-way set-associative cache in which each cache way can store only a single element of srcData.

## 3.2 Transpose-based Optimal Replacement Performance




![](https://i.imgur.com/5jp8FFc.png)


* T-OPT significantly reduces LLC MPKI compared to LRU and other policies, achieving a 41% miss rate for PageRank (compared to a 60-70% miss rate for other policies).
* The main reason T-OPT is better is that T-OPT does not  guess the re-reference pattern. Instead, T-OPT uses precise information of future reuse encoded in the graph’s transpose to make better replacement decisions

## 3.3 Limitations of Transpose-based Optimal Replacement

* A key challenge posed by T-OPT is that naively **accessing the transpose** imposes an untenable run time overhead and cache footprint

### Increased Run Time

* Finding the next reference of a vertex incurs a complexity of $O(|OutDegree|)$  of the vertex.
* Finding the next reference of a cache line involves **finding the next reference of each vertex** in the cache line (and reporting the minimum of these values)

### Increased Memory Access
* Since the vertices resident in cache can be arbitrary, the neighbor lookups using the Offset Array (OA) and Neighbor Array (NA) of the transpose (Figure 1) **incur additional irregular memory accesses** that increase cache contention with graph application data

# 4.  P-OPT: PRACTICAL OPTIMAL REPLACEMENT
* P-OPT uses a specialized data structure (called the Rereference Matrix) for fast access of re-reference information available in a graph’s transpose without incurring T-OPT’s overheads.


## 4.1  Reducing the Overheads of T-OPT
![](https://i.imgur.com/bkmpCHe.png)
### Quantizing Re-reference Information
* By quantizing next references into fewer, uniform-sized epochs, P-OPT reduces the range of next references for each vertex (spanning Epoch-0 to 2), unlike T-OPT where the next reference spans the entire range of vertices in the graph (D0 to D4)

### Rereference Matrix
* The number of cache lines is equal to the number of vertices as a cache line stores a single srcData element in Figure 3
* Each Rereference Matrix entry stores the **distance** to the epoch of a cache line’s next reuse 
    * maximum value M indicating infinity 
    * 0:this epoch will be accessed
* Instead of traversing the neighbors of each vertex in a cache line (as in T-OPT), P-OPT need only look up a single next reference for the cache line in $O(1)$
* For a graph of 32 million vertices, 64B per cache line, and 4B per srcData element, 8-bit quantization yields a Rereference Matrix column size of 2MB (32M*4B/64B * 8bits = 2M lines * 1B), consuming only a small part of a typical server CPU’s LLC

## 4.2  Tolerating Quantization Loss
![](https://i.imgur.com/5qwlXa5.png)

* Only inter-epoch reference information is tracked and an execution cannot identify a cache line’s final reference within an epoch
* MSB : whether the cache line will be accessed
    * if not : MSB = 1, lower bits encode the distance to the cache line's next reference
    * if so : MSB = 0, lower bits encode when the final access to the cache line happen in the epoch
        * sperate an epoch into many sub-epoch, encode the sub-epoch's number of the cache line's final reference 

![](https://i.imgur.com/eaqog2Z.png)
* P-OPT checks the MSB of the cache line’s Rereference Matrix entry for the current epoch (currEntry) (Line 5).
    * if currEntry[7] (MSB) = 1, return currEntry[0]~currEntry[6]
    * if MSB = 0, check if currEntry is beyond final reference
        * if so, return 0 (the cache line will be reused)
        * if not, return distance between current epoch and next reference epoch


![](https://i.imgur.com/o5LasqE.png)
* Figure 7 shows the reduction in LLC misses achieved by the different policies relative to DRRIP. 
    * P-OPT-INTER+INTRA is able to achieve LLC miss reduction close to the idealized T-OPT 

# 5.  P-OPT ARCHITECTURE

## 5.1 Storing Next References in LLC

![](https://i.imgur.com/x7vrEIi.png)
* Figure 8 shows some LLC ways reserved for current (orange) and next (blue) epoch columns of the Rereference Matrix

## 5.2 Finding a Replacement Candidate
![](https://i.imgur.com/eowaDCK.png)

* P-OPT maintains two registers – irreg_base and irreg_bound – to track the address range of a graph kernel’s irregData
    * During cache replacement, P-OPT compares the address in the tag portion of each way in the eviction set against irreg_base and irreg_bound registers to determine if the way contains an irregData cache line
* P-OPT uses a **next-ref engine** (a Finite State Machine)  to compute the next reference of each non-reserved way in the eviction set by Algorithm 2, and then stores next references in the next-ref buffer
* P-OPT maintains **next-ref buffers** at the LLC to keep track of the next references of each way in the eviction set

++steps:++
1. The next-ref engine computes next references by accessing Rereference Matrix entries for each irregData line in the eviction set
2. The next-ref engine then storing the computed next references in the next-ref buffer. 
3. The next-ref engine then searches the next-ref buffer to find the way with the **largest (i.e., furthest in future)** next reference value to evict, settling a tie using a baseline replacement policy (P-OPT uses DRRIP).

## 5.3 Streaming Rereference Matrix columns into the LLC
* To transfer Rereference Matrix entries from memory to LLC, P-OPT uses a dedicated hardware unit called the **streaming engine**
    * The programmer invokes the streaming engine at every epoch boundary using a new stream_nextrefs instruction. The instruction swaps pointers to the current and next epoch (Figure 8) and streams in the next epoch column of the Rereference Matrix into the LLC locations 
    * Doing so does not impose a performance penalty because streaming engine latency is not a performance problem because epoch boundaries are infrequent.

## 5.4 Generalizing P-OPT

* With simple extensions, P-OPT supports multi-threading, multiple irregularly-accessed datastreams, and context switches.

### Support Parallel multi-threaded Execution
* In a multi-threaded execution, multiple active vertices are being traversed at a time (i.e., a unique currDstId for each thread) and P-OPT needs to select one of the active vertices for next reference computation (Algorithm 2; Lines 8-12).
* To guarantee that all threads always process vertices in the same epoch, P-OPT requires slight modification of the application to **execute epochs serially** (vertices within an epoch are executed in parallel).
    * Due to the relatively small number of epochs (8 bits, 256 in the default P-OPT configuration) each epoch consists of a large number of vertices and restricting parallelism to only within epochs does not significantly impact performance.

### Handling Mutiple Irregular Data Streams
P-OPT can support multiple irregular data structures using three architecture changes.
1. P-OPT holds a **separate Rereference Matrix for each irregular data structure** 
2. P-OPT reserves the minimum number of ways in the LLC to hold the Rereference Matrix data for all the different irregular data structures. The system maintains a separate set-base and way-base register for each irregular data structure.
3. P-OPT **maintains an irreg_base and irreg_bound register for each irregular data structure** to use the right Rereference Matrix data corresponding to each data structure. 

### Virtualization
* The Rereference Matrix in P-OPT only tracks reuse among graph application data. 
    * If applications share LLC, **P-OPT may unfairly prefer caching graph data over other data.**
* To remain fair, we assume per-process way-partitioning and that P-OPT only replaces data in the graph-process-designated LLC ways
* P-OPT supports context switches, by saving its registers (set-base, way-base, irreg_base, irreg_bound, currVertex) with the process context
    *  On resumption, P-OPT invokes the streaming engine to refetch Rereference Matrix contents into reserved LLC ways

## 5.5 Implementation Complexity
* P-OPT has low architectural complexity.
* P-OPT only adds next-ref buffers to temporarily store next references during replacement
    * The size of next-ref buffers state is bounded by the maximum cache-level parallelism at the LLC 
* The next-ref engine is a simple FSM that only needs support for integer division and basic bit manipulation.

# 6 Evaluation

## 6.1 P-OPT Improves Performance
![](https://i.imgur.com/EsIBr82.png)

* P-OPT outperforms DRRIP across the board, with average speedup of 22% and LLC miss reduction of 24%

## 6.2  P-OPT Scales with Graph Size
![](https://i.imgur.com/RSP8m3i.png)
* We evaluate a P-OPT variant, P-OPT-Single-Epoch (P-OPT-SE), that **computes next references using only the current epoch column of the Rereference Matrix**. 
* P-OPT-SE encodes information about the next epoch within the current epoch column by repurposing the **second most significant bit** of an entry to track if the cache line is accessed in the next epoch (Figure 6). 
* P-OPT-SE stores only the current epoch column in LLC. However, the reduced cache footprint in P-OPT-SE comes at the expense of **reduced next reference quality**. 
    * Down two bits per entry, the range of next references tracked in P-OPT-SE is halved from 128 to 64 — P-OPT-SE is forced to use coarser quantization.
* With fewer than 32 million vertices, P-OPT has better LLC locality. 
    * P-OPT has better replacement information (i.e. current and next epoch) overshadows the reduction in effective LLC capacity. 
* However, in larger graphs, P-OPT-SE has better locality because of P-OPT’s high reduction in effective LLC capacity

## 6.3 P-OPT compared to prior optimizations

### Graph-agnostic improvements

![](https://i.imgur.com/AmSufrq.png)

* Unlike prior work, **P-OPT is graph-agnostic, not reliant on specific structure or vertex ordering of a graph**

#### GRASP
* GRASP is a replacement policy for graphs with very skewed degree distributions. GRASP expects a pre-processed input vertex array and GRASP uses Degree-Based Grouping (DBG) to order vertices. 
* Figure 12(a) shows locality improvements from GRASP and P-OPT for PageRank on DBG-ordered graphs. P-OPT outperforms GRASP in three ways : 
    1. GRASP works well for graphs with skewed degree distributions, but is less effective for other inputs, P-OPT is agnostic to graph structure, offering consistent improvement
    2. even for skewed graphs, P-OPT has higher LLC miss reduction than GRASP
    3. GRASP requires the input graph to be reordered (using DBG) whereas P-OPT is applicable across any vertex ordering

#### HATS-BDFS
* HATS-BDFS is a dynamic vertex-scheduling architecture, it runs hardware Bounded Depth First Search (BDFS) to schedule vertices, yielding locality improvements in graphs with community structure
* Figure 12(b) compares P-OPT on the standard vertex schedule (“Vertex Ordered” per HATS) against HATS-BDFS. The data shows that HATS-BDFS’s improvements are sensitive to graph structure. 
    * for graph with community-structured, BDFS offers locality improvements, even outpacing T-OPT because BDFS improves locality at all cache levels. 
    * However, for graphs without community structure (even power-law graphs such as DBP and KRON), BDFS increases LLC misses. 
    * In contrast, P-OPT offers consistent LLC locality improvements, leading to a higher mean LLC miss reduction compared to HATS-BDFS


## 6.4 Sensitivity Studies
### Sensitivity to quantization level
![](https://i.imgur.com/Uphe9EL.png)
* Figure 15 shows P-OPT’s performance with 4-bit, 8-bit, and 16-bit quantization in the Rereference Matrix
* On average, we observe that for P-OPT with 4b, 8b, and 16b quantization of rereferences, 41%, 12%, and 0% of all LLC replacements respectively result in a tie
* The already low percentage of replacement ties at 8b quantization explains why P-OPT sees little benefit with higher precision.

### Sensitivity to LLC parameters
![](https://i.imgur.com/rxrP81S.png)
* The benefit offered by P-OPT over DRRIP increases with LLC capacity because the fraction of LLC consumed for Rereference Matrix columns reduces. 
* P-OPT also offers higher miss reduction with higher LLC associativity. As associativity increases, P-OPT has more options for replacement and makes a better choice by considering next references of all ways in the eviction set

### Preprocessing cost of P-OPT
![](https://i.imgur.com/AlJISqU.png)
* The main performance results (Figure 10) omitted preprocessing costs because the Rereference Matrix is algorithm agnostic and needs to be created only once for a graph.
* On average, constructing the Rereference Matrix accounts for 19.8% of PageRank runtime
* Since the Rereference Matrix is algorithm agnostic, the preprocessing cost of P-OPT can be easily amortized by reusing the Rereference Matrix across multiple applications running on the same graph