{"componentChunkName":"component---src-templates-post-template-js","path":"/posts/operatingsystems/caching","result":{"data":{"markdownRemark":{"id":"95f28f6d-a3c9-598d-9fac-3f0ff50bd8d5","html":"<h2 id=\"examples-of-caches\" style=\"position:relative;\"><a href=\"#examples-of-caches\" aria-label=\"examples of caches permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Examples of Caches</h2>\n<ol>\n<li><strong>TLBs:</strong> Caches recent results of address translation from page tables.</li>\n<li><strong>Virtually addressed caches:</strong> Stores memory value associated with a virtual address</li>\n<li><strong>Physically addressed caches:</strong> This is a part of the virtually addressed cache. Each entry stores the memory value associated with a physical memory location.</li>\n<li>DNS caches, Web content caches, web search, email clients, incremental compilation, just in time translation, virtual memory, file systems, conditional branch prediction all use caches.</li>\n</ol>\n<h2 id=\"design-challenges-of-caches\" style=\"position:relative;\"><a href=\"#design-challenges-of-caches\" aria-label=\"design challenges of caches permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Design Challenges of Caches</h2>\n<ul>\n<li><strong>Locating the cached copy:</strong> Check if the value you are looking for is in the cache</li>\n<li><strong>Replacement Policy:</strong> Which elements should be replaced when the cache is full?</li>\n<li><strong>Coherence:</strong> What should we do when the cache is out of date?</li>\n</ul>\n<h2 id=\"naive-cache-implementation\" style=\"position:relative;\"><a href=\"#naive-cache-implementation\" aria-label=\"naive cache implementation permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Naive Cache Implementation</h2>\n<ul>\n<li>An (address, value) pair stored in a map. When looking for something, we check if it exists in the map and return the value if it does(aka a cache hit). If it doesn’t this is a cache miss.</li>\n<li>The cost of retrieving data out of the cache must be less than fetching the data from memory. The likelihood of a cache hit must be high enough to be worth the effort.</li>\n<li>Two sources of predictability are temporal locality and spatial locality. Programs tend to reference the same instructions and data they recently referenced(Temporal Locality). Programs also tend to reference data that is near recently referenced data.</li>\n<li><code class=\"language-text\">Latency(read request)=Prob(cache hit) × Latency(cache hit)+ Prob(cache miss) × Latency(cache miss)</code></li>\n<li><strong>Write through cache:</strong> All updates are sent immediately onward to memory</li>\n<li><strong>Write back cache:</strong> Updates are stored in the cache and only sent to memory when the cache runs out of space.</li>\n</ul>\n<h2 id=\"memory-hierarchy--when-to-use-caches\" style=\"position:relative;\"><a href=\"#memory-hierarchy--when-to-use-caches\" aria-label=\"memory hierarchy  when to use caches permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Memory Hierarchy + When to use Caches</h2>\n<ul>\n<li>Fundamental tradeoff: the smaller memory is, the faster it can be. The slower memory is, the cheaper it can be.</li>\n</ul>\n<h3 id=\"working-sets\" style=\"position:relative;\"><a href=\"#working-sets\" aria-label=\"working sets permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Working Sets</h3>\n<ul>\n<li>A sufficiently large cache will have a high cache hit rate, since if you can fit all the memory and data, the miss rate will be 0.</li>\n<li>Most programs have an inflection point where a critical mass of program data can just barely fit inside the cache. This is known as a <em>working set</em></li>\n<li><strong>Thrashing:</strong> Occurs when a cache is too small to fit inside the working set.</li>\n</ul>\n<h3 id=\"zipf-model\" style=\"position:relative;\"><a href=\"#zipf-model\" aria-label=\"zipf model permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Zipf Model</h3>\n<ul>\n<li><strong>Motivation:</strong> New data is constantly being added to the web, it is likely that your cache is outdated when you request something from it. There is no working set for the web, a small amount of pages might be useful(gmail, facebook, youtube) but there is a huge amount of web pages that are only visited from time to time.</li>\n<li>Zipf can be described as\n<code class=\"language-text\">Frequency of visits to the kth most popular page ∝ 1 / kα</code>\nand can model the popularity of library books, the population of cities, salary distribution, number of facebook friends, etc.</li>\n<li><strong>Heavy tailed distribution:</strong> A significant number of references will be the most popular items, but a substantial portion will be less popular ones.</li>\n</ul>\n<h2 id=\"cache-design\" style=\"position:relative;\"><a href=\"#cache-design\" aria-label=\"cache design permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Cache Design</h2>\n<ul>\n<li><strong>Fully associative:</strong> Addresses can be stored anywhere in the cache, there is no ordering. When looking for an address, we check every entry in the cache: there is a cache hit if any of the entries match.\nCons: This is really slow as caches becomes bigger.</li>\n<li><strong>Direct mapped:</strong> Each address is hashed then the data stored at the location of the hash.\nCons: If two different addresses hash to the same entry, the system will thrash.</li>\n<li><strong>Set associative:</strong> The cache hashes the address to get a location, then checks the entry in each table in parallel. It returns the value if any entries match the address.</li>\n</ul>\n<h2 id=\"replacement-policies\" style=\"position:relative;\"><a href=\"#replacement-policies\" aria-label=\"replacement policies permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Replacement Policies</h2>\n<p><strong>Motivation:</strong> If we look up an address and find that it is a miss, how do we choose which memory block to replace?</p>\n<h3 id=\"random\" style=\"position:relative;\"><a href=\"#random\" aria-label=\"random permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Random</h3>\n<ul>\n<li><strong>How it works:</strong> Choose a random block to replace.</li>\n<li><strong>Pros:</strong> Randomly evicting a block is fast, thus it is good for first-level hardware caches. Non-pessimal, randomness will never be the worst possible choice on average.</li>\n<li><strong>Cons:</strong> Unpredictable, it might counteract an application that tries to take advantage of the cache.</li>\n</ul>\n<h3 id=\"first-in-first-outfifo\" style=\"position:relative;\"><a href=\"#first-in-first-outfifo\" aria-label=\"first in first outfifo permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>First in First Out(FIFO)</h3>\n<ul>\n<li><strong>How it works:</strong> Evict the cache block or page that has been in memory the longest.</li>\n<li><strong>Pros:</strong> Each page spends an equal amount of time in the cache.</li>\n<li><strong>Cons:</strong> Imagine a program that cycles through an array, where the array is too large to fit into the cache. Then the cache is useless.</li>\n</ul>\n<h3 id=\"optimal-cache-replacement-min\" style=\"position:relative;\"><a href=\"#optimal-cache-replacement-min\" aria-label=\"optimal cache replacement min permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Optimal Cache Replacement (MIN)</h3>\n<ul>\n<li><strong>How it works:</strong> Replace whichever block that is used farthest in the future.</li>\n<li><strong>Pros:</strong> This is optimal. (aka the best possible algorithm)</li>\n<li><strong>Cons:</strong> Impossible, MIN requires knowledge of the future.</li>\n</ul>\n<h3 id=\"least-recently-used-lru\" style=\"position:relative;\"><a href=\"#least-recently-used-lru\" aria-label=\"least recently used lru permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Least Recently Used (LRU)</h3>\n<ul>\n<li><strong>How it works:</strong> Evict the block that has not been used for the longest period of time. In software, this is done with a linked list. In hardware, it is approximated with the clock algorithm</li>\n<li><strong>Pros:</strong> Takes advantage of temporal locality</li>\n<li><strong>Cons:</strong> Weak when the task is repeated scans through an array, the optimal strategy there is FIFO</li>\n</ul>\n<h3 id=\"least-frequently-usedlfu\" style=\"position:relative;\"><a href=\"#least-frequently-usedlfu\" aria-label=\"least frequently usedlfu permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Least Frequently Used(LFU)</h3>\n<ul>\n<li><strong>How it works:</strong> Discard the page used least often</li>\n<li><strong>Pros:</strong> Good in web caching. Ie just because we recently looked at spas in Iceland doesn’t mean we will frequently look at spas in Iceland. Frequency is a better approximation than time.</li>\n<li><strong>Cons:</strong> If an item is referenced repeatedly for a short period of time, this will stay in the cache long after it should have been evicted.</li>\n</ul>\n<h3 id=\"beladys-anomaly\" style=\"position:relative;\"><a href=\"#beladys-anomaly\" aria-label=\"beladys anomaly permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Belady’s Anomaly</h3>\n<p>Intuitively, adding space to a cache should always improve or maintain the cache hit rate. However, <em>Belady’s Anomaly</em> says this isn’t the case.</p>\n<p>For some replacement policies like FIFO, adding more space will drastically change the contents of the cache, thus making the hit rate worse.</p>\n<h2 id=\"memory-mapped-files\" style=\"position:relative;\"><a href=\"#memory-mapped-files\" aria-label=\"memory mapped files permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Memory Mapped Files</h2>\n<p><strong>Demand Paging:</strong> Applications can access more memory than is physically present on the machine by using memory pages as a cache for disk blocks.\n<strong>Memory Mapped File:</strong> The program directly accesses and modifies the contents of the file, treating memory as a write-back cache for disk.</p>\n<h3 id=\"pros\" style=\"position:relative;\"><a href=\"#pros\" aria-label=\"pros permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Pros</h3>\n<ul>\n<li><strong>Transparency:</strong> The program can write directly into the file as if it was memory</li>\n<li><strong>Zero copy I/O:</strong> The OS does not need to copy file data from kernel buffers into user memory and back, it can just change the program’s page table entry to point to the physical page frame containing that part of the file.</li>\n<li><strong>Pipelining:</strong> The program can operate on data in the file as soon as page tables are set up, no need to wait for the entire file to be read into memory.</li>\n<li><strong>Interprocess communication:</strong> Two processes can share memory via a memory mapped file.</li>\n<li><strong>Large Files:</strong> The only size limit of a memory mapped file is the size of the virtual address space.</li>\n</ul>\n<h3 id=\"implementation\" style=\"position:relative;\"><a href=\"#implementation\" aria-label=\"implementation permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Implementation</h3>\n<p>OS provides a system call where the kernel initializes a set of page table entries for that region of virtual address space, setting each entry to invalid.</p>\n<p>When the process gives an instruction that touches an invalid mapped address:</p>\n<ol>\n<li>The TLB miss occurs, triggering a full page table lookup in hardware.</li>\n<li>The hardware finds the page table entry and finds that it is invalid, causing a <em>hardware page fault</em> into the OS kernel.</li>\n<li>The OS kernel converts the address to a file offset.</li>\n<li>The OS kernel allocates an empty page frame and reads the required file block into the empty page frame.</li>\n<li>The disk interrupts the processor when the file block has been read and the scheduler resumes handling the page fault exception.</li>\n<li>The kernel updates the page table entry to point to the page frame allocated for the block and sets the entry to valid.</li>\n<li>The OS resumes execution of the process.</li>\n<li>The TLB misses, trigger a full page table lookup.</li>\n<li>The hardware returns the page frame to the processor, loads the TLB with the new translation, evicts the previous TLB entry, then uses the translation to construct a physical address.</li>\n</ol>\n<p>To create the empty page frame that holds the incoming page from disk, the OS:</p>\n<ol>\n<li>Selects a page to evict using the current replacement policy.</li>\n<li>Finds page table entries that point to the evicted page, usually through a core map.</li>\n<li>Set each page table entry to invalid, to prevent other processes from using the evicted page while it is being evicted.</li>\n<li>Copy back any changes to the evicted page.</li>\n</ol>\n<h2 id=\"approximating-lru\" style=\"position:relative;\"><a href=\"#approximating-lru\" aria-label=\"approximating lru permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Approximating LRU</h2>\n<p>Keeping a linked list to track when pages were last used in hardware is prohibitively expensive, thus, we will use the clock algorithm as an approximation instead.</p>\n<h3 id=\"clock-algorithm\" style=\"position:relative;\"><a href=\"#clock-algorithm\" aria-label=\"clock algorithm permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Clock algorithm</h3>\n<p>The OS scans through the core map of physical memory pages. 2. For each page frame, it records the value of the use bit and clears the use bit. 3. The OS does a shootdown for each page frame that has its use bit cleared.</p>\n<p>A common usage of the collected values of the use bit is the <strong>not recently used/kth chance algorithm</strong> where the kernel picks a page that has not been set for the last k sweeps of the clock algorithm.</p>\n<h2 id=\"virtual-memory\" style=\"position:relative;\"><a href=\"#virtual-memory\" aria-label=\"virtual memory permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Virtual Memory</h2>\n<p>By backing every memory segment with a file on disk, we create virtual memory.</p>\n<h3 id=\"self-paging\" style=\"position:relative;\"><a href=\"#self-paging\" aria-label=\"self paging permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Self Paging</h3>\n<p><strong>Problem:</strong> There is a malicious program that tries to grab as much memory as possible by using multiple threads to cycle through memory and add those pages.\n<strong>Solution:</strong> Self paging assigns every process its fair share of page frames. As the system starts to page, it evicts the page from whichever process has the most pages allocated to it.\n<strong>Cons:</strong> If there are two processes, one with a working set of 2/3 of memory and the other with 1/3 of memory, the ideal split is for the first process to get 2/3 of memory and the other to get 1/3 of memory. Unfortunately, self-paging will results in both process splitting the memory, causing the first process to thrash</p>\n<h3 id=\"swapping\" style=\"position:relative;\"><a href=\"#swapping\" aria-label=\"swapping permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Swapping</h3>\n<p><strong>Problem:</strong> Sometimes, there is simply too much data in all of the process’ working sets to effectively run them at once. If we try to run things normally, we will end up thrashing with every process.\n<strong>Solution:</strong> We can evict an entire process from memory (aka swapping)\n<strong>Cons:</strong> The process that just got evicted from memory will be sad :(</p>\n<h1 id=\"future\" style=\"position:relative;\"><a href=\"#future\" aria-label=\"future permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Future</h1>\n<ol>\n<li><strong>Low latency backing store:</strong> Things that were once on hard disk are moving onto SSDs, things that are on SSDs will move onto even faster storage devices.</li>\n<li><strong>Variable page sizes:</strong> We will move toward smaller effective page sizes due to low latency solid state storage and cluster memory.</li>\n<li><strong>Memory aware applications:</strong> Applications can be tuned to how much memory is in the first level cache to increase performance.</li>\n</ol>\n<h1 id=\"questions\" style=\"position:relative;\"><a href=\"#questions\" aria-label=\"questions permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Questions</h1>\n<ol>\n<li>How does set associative caches work?</li>\n<li>How does virtual memory work?</li>\n</ol>","fields":{"slug":"/posts/operatingsystems/caching","tagSlugs":["/tag/notes/","/tag/textbook/","/tag/operating-system/"]},"frontmatter":{"date":"2021-10-22T23:46:37.121Z","description":"Notes on caching for operating systems","tags":["Notes","Textbook","Operating System"],"title":"Caching"}}},"pageContext":{"slug":"/posts/operatingsystems/caching"}},"staticQueryHashes":["251939775","401334301","825871152"]}