<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Dispatch on 0xc0de</title>
    <link>https://0xc0de.xyz/tags/dispatch/</link>
    <description>Recent content in Dispatch on 0xc0de</description>
    <image>
      <title>0xc0de</title>
      <url>https://0xc0de.xyz/%3Clink%20or%20path%20of%20image%20for%20opengraph,%20twitter-cards%3E</url>
      <link>https://0xc0de.xyz/%3Clink%20or%20path%20of%20image%20for%20opengraph,%20twitter-cards%3E</link>
    </image>
    <generator>Hugo</generator>
    <language>zh-tw</language>
    <lastBuildDate>Sat, 10 May 2025 00:00:00 +0800</lastBuildDate>
    <atom:link href="https://0xc0de.xyz/tags/dispatch/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>&lt;超標量處理器概覽&gt; 第 11 章 - 真實世界的例子：Alpha 21264 處理器</title>
      <link>https://0xc0de.xyz/posts/superscalar-overview-ch11/</link>
      <pubDate>Sat, 10 May 2025 00:00:00 +0800</pubDate>
      <guid>https://0xc0de.xyz/posts/superscalar-overview-ch11/</guid>
      <description>&lt;h1 id=&#34;111----概述&#34;&gt;11.1 -  概述&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;DEC 的 Alpha 21264 是 superscalar CPU 的一個典範，其為 4-way out-of-order superscalar CPU，工作頻率是 466 ~ 667 MHz，benchmark：SPECint95 - 40、SPECfp95 - 86；與同時期其他的處理器 benchmark 對比：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;image.png&#34; loading=&#34;lazy&#34; src=&#34;https://0xc0de.xyz/posts/superscalar-overview-ch11/image.png&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Alpha 21264 的 pipeline 最多同時支持 80 條指令，以及 80 個 checkpoints，因此對於 branch mis-prediction、exception、interrupt，Alpha 21264 都可以快速地恢復 CPU 狀態&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Alpha 21264 的分支預測器實現了基於局部歷史 (Local prediction) 和基於全局歷史 (Global prediction) 兩種預測方式，並根據程式的執行情況，動態選擇預測率最高的方法，這就像是兩種分支預測方式在進行競爭一樣&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;對於 load/store 指令，Alpha 21264 採用了 Speculative Memory Disambiguation 和 Load hit/miss Prediction&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Alpha 21264 採用 7-stage pipeline，比較短的 pipeline 使 branch mis-prediction 發生時的 mis-penalty 比較低，從而提高處理器的效率：&lt;/p&gt;</description>
      <content:encoded><![CDATA[<h1 id="111----概述">11.1 -  概述</h1>
<ul>
<li>
<p>DEC 的 Alpha 21264 是 superscalar CPU 的一個典範，其為 4-way out-of-order superscalar CPU，工作頻率是 466 ~ 667 MHz，benchmark：SPECint95 - 40、SPECfp95 - 86；與同時期其他的處理器 benchmark 對比：</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image.png"></p>
</li>
<li>
<p>Alpha 21264 的 pipeline 最多同時支持 80 條指令，以及 80 個 checkpoints，因此對於 branch mis-prediction、exception、interrupt，Alpha 21264 都可以快速地恢復 CPU 狀態</p>
</li>
<li>
<p>Alpha 21264 的分支預測器實現了基於局部歷史 (Local prediction) 和基於全局歷史 (Global prediction) 兩種預測方式，並根據程式的執行情況，動態選擇預測率最高的方法，這就像是兩種分支預測方式在進行競爭一樣</p>
</li>
<li>
<p>對於 load/store 指令，Alpha 21264 採用了 Speculative Memory Disambiguation 和 Load hit/miss Prediction</p>
</li>
<li>
<p>Alpha 21264 採用 7-stage pipeline，比較短的 pipeline 使 branch mis-prediction 發生時的 mis-penalty 比較低，從而提高處理器的效率：</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%201.png"></p>
</li>
<li>
<p>Alpha 21264 所使用的設計理念是領先於那個時代的，包含競爭的分支預測、store/load 指令間的相關性預測，數量豐富的 checkpoints 等，它的設計理念被用到了未來的 AMD 和 Intel CPU 中，直接或間接地影響了現代電腦產業</p>
</li>
</ul>
<h1 id="112---取指令和分支預測">11.2 - 取指令和分支預測</h1>
<ul>
<li>Alpha 21264 每個 cycle 可以從 I-Cache 中讀取四條指令進 pipeline，其 I-Cache 的 size 為 64 KB、採用 2-way associative，並使用了 2 個 stages 來讀取 I-Cache：<code>fetch0</code> 和 <code>fetch1</code>
<ul>
<li><code>fetch0</code>：讀取 I-Cache，但這個 cycle 只能得到 I-Cache 的指令 (i.e. data) 和 tag，無法再做其他的事情</li>
<li><code>fetch1</code>：進行 tag 比對的同時，還會將指令送到 decoder 和 register renaming 相關的元件
<ul>
<li>在 Alpha 21264 中，這個傳輸需要跨越大半個晶片，比較花時間，這也是 Alpha 21264 使用了 2 個 stages 來讀取 I-Cache 的原因</li>
</ul>
</li>
</ul>
</li>
<li>Alpha 21264 每個 cycle 都需要向 I-Cache 發送位址來讀取指令，為了盡早察覺到分支指令和分支指令的目標位址，Alpha 21264 透過兩個方法來提昇 instruction fetch 的準確度：
<ul>
<li>line/way 的預測 - 較簡單的分支預測器，可以在 <code>fetch0</code> 就得到結果，但是預測準確度比較低</li>
<li>分支預測 - 較複雜的分支預測器，需使用 2 個 cycles，也就是 <code>fetch1</code> 才能得到結果，但是預測準確度比較高
<ul>
<li>如果發現 <code>fetch0</code> 的預測結果與 <code>fetch1</code> 的預測結果不符，則會拋棄 <code>fetch0</code> 的預測結果，使用 <code>fetch1</code> 的預測結果來 fetch instruction，但也會因此產生 1 個 cycle 的 bubble
<ul>
<li>i.e. 使用 <code>fetch0</code> 的預測結果讀進來的 instruction 會被 flushed 掉</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="1121---lineway-的預測">11.2.1 - line/way 的預測</h2>
<ul>
<li>
<p>Alpha 21264 在 fetch stage，為了可以盡快地從 I-Cache fetch 指令，對 I-Cache 的 instruction fetch 位址也進行了預測，這就是 <strong>line/way 預測</strong></p>
<ul>
<li>這種方法本質上就是將 BTB 放進了 I-Cache 中</li>
</ul>
</li>
<li>
<p>由於 Alpha 21264 每個 cycle fetch 的四條指令必須是 4 words aligned 的，因此只需要對每條 cache line 中每一組 4 words aligned 的四條指令使用一個 line/way 預測即可：</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%202.png"></p>
<ul>
<li>對於一條 64 bytes 的 cache line，需要使用 4 個 line/way 預測 (64 bytes / (4 words * 4 bytes/word) = 4)，每個 line/way 預測包含了以下的資訊：
<ul>
<li><code>Successor way</code>：
<ul>
<li>下一個 cycle 要取的 fetch group，位在 I-Cache 的那個 way
<ul>
<li>E.g. 4-way set-associative I-Cache，共需要 2 bits 來表示</li>
</ul>
</li>
</ul>
</li>
<li><code>Successor index</code>：
<ul>
<li>下一個 cycle 要取的 fetch group，第一條指令在 cache line 中的位置
<ul>
<li>E.g. 一個 64 KB、2-way set-associative cache、cache line 為 64 bytes 的 I-Cache：
<ul>
<li>需使用 <code>PC[14:6]</code> ⇒ <strong>9 bits</strong> (64 KB / 2-way set-associative / 64 byes = 512 bytes) 來找到一條 cache line</li>
<li>需使用 <code>PC[5:2]</code> ⇒ <strong>4 bits</strong> (64 bytes / 4 bytes/word ⇒ 16，一條 cache line 中共有 16 個 words) 來找到 cache line 中的某個 word</li>
<li>因此，<code>Successor index</code> 只需儲存 <code>PC[14:2]</code> ⇒ <strong>13 bits</strong> 即可</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><code>Branch position</code>：
<ul>
<li>此 cycle 所取出的 fetch group 中，如果存在分支指令，則將這條分支指令的下一條指令的位址資訊記錄在 <code>branch position</code> 欄位</li>
<li>之所以不記錄分支指令本身的位址資訊，而是其下一條指令的位址資訊，是因為如果此 cycle 取出的 fetch group 中存在預測會跳轉的分支指令，則它後面的指令都不會進入 pipeline，但分支指令本身是會進入 pipeline 的
<ul>
<li>因此記錄分支指令的下一條指令的位址資訊更容易找到此 cycle 所取出的 fetch group 中，哪些指令不應該進入 pipeline</li>
<li>當此 cycle 所取出的 fetch group 中不存在分支指令，或是存在預測結果為不跳轉的分支指令時，只需將 <code>branch position</code> 寫入 <code>2’b00</code>，就可以表示 “此 cycle 取出的 fetch group 中的所有指令，都需要進 pipeline” 了</li>
<li>如果預測跳轉的分支指令是這個 fetch group 的最後一條指令，那麼這個 fetch group 中的每條指令也都應該進 pipeline，同樣也只需將 <code>branch position</code> 寫入 <code>2’b00</code> 即可</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p>在 Alpha 21264 中，當一個 cache line 從 L2 Cache 讀進 L1 I-Cache 時，這條 cache line 包含的所有預測資訊都會被初始化為“沒有需要跳轉的分支指令”，此時 line/way 的預測資訊會指向下一個 PC 值，i.e. <code>PC + sizeof(fetch group)</code></p>
<ul>
<li>一旦在後面的過程中發現這個預測資訊是錯的 (e.g. <code>fetch1</code> 的預測結果與 <code>fetch0</code> 的預測結果不同)，就會修改 cache line 中的所記錄的預測資訊</li>
<li>可以按照之前 <code>2-bit saturating counter</code> 的方式來管理 line/way 的預測值，也就是只有當連續兩次預測失敗時，line/way 的預測值才會改變</li>
</ul>
</li>
<li>
<p>每個 cycle 都會依據目前 fetch group 的 line/way 的預測器，決定下個 cycle 要 fetch 的指令位址</p>
</li>
<li>
<p>範例：</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%203.png"></p>
<ul>
<li>64 KB I-Cache，2-way set-associative，每條 cache line 是 32 bytes (i.e. 32 bytes / 4 bytes/word = 8 words)，每 4 個 words 使用一個 line/way 預測器，因此每條 cache line 都包含了 2 個 line/way 預測器
<ul>
<li>可以用 <code>PC[14:2]</code> 從 I-Cache 中找到需要的指令</li>
<li>Cycle 0：
<ul>
<li><code>PC = 0x20580354</code>，對應到 way 0；由於每個 cycle fetch 的四條指令必須是 4 words aligned 的，因此只能讀出三條指令</li>
<li><code>Branch position = 2’b00</code>，因此這三條指令都會進 pipeline
<ul>
<li>i.e. A0 ~ A2 會進 pipeline</li>
</ul>
</li>
<li><code>Successor index = 0x360</code>，因此下一個要 fetch 的指令位址：<code>0x20580360</code></li>
</ul>
</li>
<li>Cycle 1：
<ul>
<li><code>PC = 0x20580360</code>，對應到 way 1；由於是 4-word aligned 的，因此四條指令都可以被讀出</li>
<li><code>Branch prediction = 2’b11</code>，因此最後一條指令不會進 pipeline
<ul>
<li>i.e. A3 ~ A5 會進 pipeline</li>
</ul>
</li>
<li><code>Successor index = 0xa28</code>，因此下一個要 fetch 的指令位址：<code>0x20580a28</code></li>
</ul>
</li>
<li>Cycle 2：
<ul>
<li>PC = <code>0x20580a28</code>，對應到 way 1；由於每個 cycle fetch 的四條指令必須是 4 words aligned 的，因此只能讀出兩條指令</li>
<li><code>Branch position = 2’b00</code>，因此這兩條指令都會進 pipeline
<ul>
<li>i.e. B0 ~ B1 會進 pipeline</li>
</ul>
</li>
<li><code>Successor index = 0xa30</code>，因此下一個要 fetch 的指令位址：<code>0x20580a30</code></li>
</ul>
</li>
<li>Cycle 3：
<ul>
<li><code>PC = 0x20580a30</code>，對應到 way 1；由於是 4-word aligned 的，因此四條指令都可以被讀出</li>
<li><code>Branch prediction = 2’b11</code>，因此最後一條指令不會進 pipeline
<ul>
<li>i.e. B2 ~ B4 會進 pipeline</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Line/way 預測方法相當於將 BTB 放到了 I-Cache 中，然後相較於獨立的 BTB：</p>
<ul>
<li>缺點：
<ul>
<li>每條 cache line 都要使用固定個數的預測資訊，例如上述範例，每條 cache line 都包含了 2 個 line/way 預測器：32 bytes cache line / (4 words * 4 bytes/word)) = 2
<ul>
<li>然而很多 cache line 中其實並沒有分支指令，浪費硬體空間</li>
<li>獨立的 BTB 不會有這個問題，因為它只會將預測結果為跳轉的分支指令放進 BTB 中</li>
</ul>
</li>
<li>隨著 cache line size 的增大，所需要的 line/way 預測器的個數也會跟著增多
<ul>
<li>E.g. 64 bytes cache line 需要使用 4 個 line/way 預測器</li>
<li>獨立的 BTB size 都是固定的，不會隨著 cache line size 的變化而改變</li>
</ul>
</li>
<li>每當一條 cache line 被 replace 時，它的 line/way 預測資訊會被預設值所取代
<ul>
<li>預設值 ⇒  <code>successor index</code> 會指到下一道 PC address</li>
<li>獨立的 BTB 則與 cache replacement 無關</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p>在 fetch1 stage 會驗證 fetch0 stage 的預測結果是否正確</p>
<ul>
<li>將 cache 的 tag (i.e. <code>PC[47:15]</code>) 與 successor index (i.e. <code>PC[14:2]</code>) 合併，就可以組成使用 line/way 預測的 PC address，在 fetch 1 stage，就可以與使用分支預測的預測結果相比，如果 PC address 不同，就代表 line/way 的預測錯誤，就會改使用 fetch1 stage 分支預測的 PC address 重新 fetch 指令
<ul>
<li>因此會產生 1 個 cycle 的 bubble，也就是 line/way 預測的 mis-penalty</li>
</ul>
</li>
<li>Alpha 21264 是使用 <a href="../superscalar-overview-ch3/#343---%E5%B0%87-tlb-%E5%92%8C-cache-%E6%94%BE%E5%85%A5%E6%B5%81%E6%B0%B4%E7%B7%9A">VIVT 架構</a>的 I-Cache，因此 PC address 可以直接比對</li>
<li>如果是使用 <a href="../superscalar-overview-ch3/#343---%E5%B0%87-tlb-%E5%92%8C-cache-%E6%94%BE%E5%85%A5%E6%B5%81%E6%B0%B4%E7%B7%9A">VIPT 架構</a>的 I-Cache，由於 tag 是 physical address，因此還需要將 fetch1 分支預測的 PC address (VA) 透過 TLB 轉換成 PA 才可以比對 line/way 的預測結果是否正確
<ul>
<li>因此，使用 line/way 預測時，使用 VIVT 架構的 I-Cache 是比較合理的設計</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Line/way 預測總結：</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%204.png"></p>
</li>
</ul>
<h2 id="1122---分支預測">11.2.2 - 分支預測</h2>
<ul>
<li>
<p>為了獲得準確的分支預測，Alpha 21264 使用的分支預測器是比較複雜的，因此無法在 fetch0 stage 完成，需要使用 2 個 stages，在 fetch1 stage 才可以獲得預測結果</p>
<ul>
<li>這個結果會和 line/way 的預測結果做比較，如果發現不一致，就以分支預測的結果為主</li>
</ul>
</li>
<li>
<p>Alpha 21264 使用了競爭的分支預測法 (tournament branch prediction)；有些分支指令使用基於全局歷史的預測方法準確度比較高，有些分支指令則是使用基於局部歷史的預測方法準確度比較高，Alpha 21264 則是兩種預測方法都實現了；對於每條分支指令來說，處理器會根據兩種分支預測方法的準確度，動態地替每條分支指令選擇適合的分支預測方法，相當於這兩種分支預測方法彼此在競爭</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%205.png"></p>
<ul>
<li>
<p>左邊為基於局部歷史的分支預測器：</p>
<ul>
<li>Local history table ⇒ <strong>BHT</strong>：
<ul>
<li>大小為 1024 x 10 bits，也就是使用了 10 bits 的 BHR，可以記錄一條分支指令過去 10 次的分支結果，總共可以記錄 1024 條分支指令的歷史記錄</li>
</ul>
</li>
<li>Local prediction ⇒ <strong>PHT</strong>：
<ul>
<li>Alpha 21264 的 local history PHT 共包含了：2^10 = 1024 個 <code>saturating counter</code>，每個 saturating counter 為 3 bits (i.e. <code>3 bits saturating counter)</code>
<ul>
<li>共需：1024 x 3 bits</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p>右邊為基於全局歷史的分支預測：</p>
<ul>
<li>Path history ⇒ <strong>GHR</strong>
<ul>
<li>GHR 為 12 bits，可以記錄過去 12 條分支指令的分支結果</li>
</ul>
</li>
<li>global prediction ⇒ <strong>PHT</strong>：
<ul>
<li>Alpha 21264 的 global history PHT 共包含了：2^12 = 4096 個 <code>saturating counter</code>，每個 saturating counter 為 2 bits (i.e. <code>2 bits saturating counter)</code>
<ul>
<li>共需：4096 x 2 bits</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Alpha 21264 基於局部歷史的分支預測器，採用了 <strong>non-speculative</strong> 的更新方法</p>
<ul>
<li>只有當指令 retire 時，才會更新分支預測器的內容 (e.g. BHR、saturating counter… etc)</li>
</ul>
</li>
<li>
<p>Alpha 21264 基於全局歷史的分支預測器，採用了 <strong>speculative</strong> 的更新方法</p>
<ul>
<li>一旦有分支指令得到預測結果，就將這個預測結果更新到 GHR 中
<ul>
<li>i.e. GHR 的狀態有可能是不正確的</li>
</ul>
</li>
<li>為了在 mis-prediction 時恢復 GHR，因此採用了 <a href="../superscalar-overview-ch4-part1/#425---%E5%88%86%E6%94%AF%E9%A0%90%E6%B8%AC%E7%9A%84%E6%9B%B4%E6%96%B0">Checkpoint GHR</a>；在更新 GHR 前，會將目前的 GHR 內容複製到 Checkpoint GHR 中；當發生 mis-prediction 時，就可以透過這個 Checkpoint GHR 來恢復 GHR</li>
</ul>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%206.png"></p>
</li>
</ul>
</li>
<li>
<p>對於 PHT 的 saturating counters 一般都是在分支指令得到確定的結果後才更新 (參考：<a href="../superscalar-overview-ch4-part1/#425---%E5%88%86%E6%94%AF%E9%A0%90%E6%B8%AC%E7%9A%84%E6%9B%B4%E6%96%B0">link</a>)</p>
</li>
</ul>
<h1 id="113---暫存器重命名">11.3 - 暫存器重<strong>命名</strong></h1>
<ul>
<li>
<p>Alpha 21264 <a href="../superscalar-overview-ch7/#723---%E4%BD%BF%E7%94%A8%E7%B5%B1%E4%B8%80%E7%9A%84-prf-%E4%BE%86%E5%AF%A6%E5%81%9A%E6%9A%AB%E5%AD%98%E5%99%A8%E9%87%8D%E5%91%BD%E5%90%8D">使用了統一的 PRF 來實做暫存器重命名</a>，整個處理器中只有一個 PRF，一個 register 在它整個生命週期只會存在一的地方，不會發生位置的變化</p>
<ul>
<li>Register renaming 消除了 WAW 和 WAR 相關性</li>
</ul>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%207.png"></p>
</li>
<li>
<p>Alpha 指令集中有一個特殊的 <code>CMOV (Conditional-move)</code> 指令，格式為：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-1">1</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-asm" data-lang="asm"><span style="display:flex;"><span><span style="color:#a6e22e">CMOV</span>  <span style="color:#66d9ef">Ra</span>, <span style="color:#66d9ef">Rb</span> <span style="color:#960050;background-color:#1e0010">?</span> <span style="color:#66d9ef">Rc</span>  <span style="color:#75715e"># (Ra == 0) ? Rc = Rb : Rc = Rc
</span></span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>這條指令在 register renaming stage，需要讀取三個 source registers：<code>Ra</code>, <code>Rb</code>, <code>Rc</code>
<ul>
<li>
<p>由於 <code>Rc</code> 同時也是 destination register，因此需要分配一個 physical register 來存舊的 <code>Rc</code> 值，並再替 destination register：<code>Rc</code>，分配另一個 physical register</p>
</li>
<li>
<p>然而，對於 Alpha 的其他指令，都只需要讀取兩個 source registers 即可，因此不值得特別為 <code>CMOV</code> 指令增加 RAT 的 read port</p>
</li>
<li>
<p><code>CMOV</code> 指令可以拆解為下列兩條指令：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-1-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-1-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-2">2</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-asm" data-lang="asm"><span style="display:flex;"><span><span style="color:#a6e22e">CMOV1</span>  <span style="color:#66d9ef">Ra</span>, <span style="color:#66d9ef">oldRc</span> -<span style="color:#960050;background-color:#1e0010">&gt;</span> <span style="color:#66d9ef">newRc1</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">CMOV2</span>  <span style="color:#66d9ef">newRC1</span>, <span style="color:#66d9ef">Rb</span> -<span style="color:#960050;background-color:#1e0010">&gt;</span> <span style="color:#66d9ef">newRc2</span>
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>透過這樣的方式，可以讓 <code>CMOV</code> 指令的 register renaming 按照一般的指令來處理，只是會需要分配兩個 physical registers</li>
</ul>
</li>
</ul>
</li>
<li>Alpha 21264 是一個 4-way superscalar CPU，每個 cycle 可以對四條指令做 register renaming，但如果這四條指令中存在 <code>CMOV</code> 指令，則會導致一個 cycle 內要對五條指令 register renaming
<ul>
<li>
<p>Alpha 21264 採用了比較簡單的方法，限制在做 register renaming 時，如果碰到 <code>COMV</code> 指令，則只有 <code>CMOV1</code> 指令以及其之前的指令可以在該 cycle 做 register renaming，<code>CMOV2</code> 以及其之後的指令必須等到下個 cycle 才可以做 register renaming</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%208.png"></p>
</li>
<li>
<p>雖然這樣的作法會讓 CPU 的執行效率有所降低，但 <code>CMOV</code> 指令出現的頻率並不高，且這種方法很容易實現，所以是一種可接受的折衷方法</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h1 id="114---發射">11.4 - 發射</h1>
<ul>
<li>Alpha 21264 包含了兩個 Issue Queue：Integer Issue Queue 以及 Floating-point Issue Queue，分別用來儲存整數類型的指令和浮點數類型的指令
<ul>
<li>Integer Issue Queue 可以儲存 20 條指令，並被 4 個 Integer FU 共享，每個 cycle 最多可以從 Integer Issue Queue 中選出 4 條整數指令出來執行</li>
<li>Floating-point Issue Queue 可以儲存 15 條指令，並被 2 個 Floating-point FU 共享，每個 cycle 可以從 Floating-point Issue Queue 中選出 2 條浮點數指令出來執行</li>
</ul>
</li>
<li>Alpha 21264 採用了 cluster 架構，將整數執行部份分成了 Cluster0 和 Cluster1 兩個部份，每個 cluster 都有完整的 Integer PRF，因此在處理器中共有兩個一模一樣的 Integer PRF
<ul>
<li>
<p>每個 cluster 內部又被分成了兩個 subcluster，分別為：upper (U) 和 lower (L)</p>
<ul>
<li>整數部份的 4 個 FU分佈在這幾個 subclusers 中：Cluster0 的 U0、L0 以及 Cluster1 的 U1、L1</li>
</ul>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%209.png"></p>
<ul>
<li>Alpha 21264 並沒有直接實現 4-of-20 的 select 電路，而是：
<ul>
<li>Cluster0 中的 U0 和 U1 共用同一個 select 電路：select0</li>
<li>Cluster1 中的 L0 和 L1 共用同一個 select 電路：select1</li>
</ul>
</li>
<li>這樣每個 select 電路只需要實做 2-of-20 的功能即可</li>
</ul>
</li>
</ul>
</li>
<li>Alpha 21264 採用了 <a href="../superscalar-overview-ch8-part1/#813---%E5%A3%93%E7%B8%AE-vs-%E9%9D%9E%E5%A3%93%E7%B8%AE">Compressing Issue Queue</a>，使 select 電路可以很容易地實現 oldest-first 的功能，不過會增加 Issue Queue 的複雜度，功耗由於每條指令被 issued 時，都會需要移動大量的指令 (通常 oldest-first 的指令都是在 Issue Queue 的底部)，因此不適合使用在行動裝置上</li>
<li>Alpha 21264 中，除了 load 指令外，其他類型指令執行所需的 cycles 數都是固定的；Alpha 21264 簡化了 load 指令的 wake-up 機制：當 load 指令發生 D-Cache miss 時，在它的 <a href="../superscalar-overview-ch8-part2/#853---%E6%8E%A8%E6%B8%AC%E5%96%9A%E9%86%92">SW (Speculative Window)</a> 中的所有指令都會從 pipeline 中被 flushed 掉，這些指令會重新在 Issue Queue 中等待被 wake up，然後參與仲裁；對於那些與 load 無關的指令很快就會再次被 select 電路選中，然而那些與 load 指令相關的指令則需要等待 D-Cache miss 被解決
<ul>
<li>這種方式雖然降低了一點性能，但比較容易實現，因為不用識別 SW 中哪些指令和 load 指令存在相關性 (參考：<a href="../superscalar-overview-ch8-part2/#853---%E6%8E%A8%E6%B8%AC%E5%96%9A%E9%86%92">link</a>)，是一種可以接受的折衷方法</li>
</ul>
</li>
<li>為了配合上述的 wake-up 機制，指令在被 select 電路選中後，不能馬上”離開” Issue Queue，而是需要確認這條指令沒有被發生 D-Cache miss 的 load 指令所影響後，才能離開 Issue Queue
<ul>
<li>因此，一條指令被 select 電路選中後，在 Issue Queue 中需要等待 2 個 cycles，才可以從 Issue Queue 中刪除該指令
<ul>
<li><em>Cycle n</em>：
<ul>
<li>指令被 select 電路選中</li>
</ul>
</li>
<li><em>Cycle n + 1</em>：
<ul>
<li>指令仍會留在 Issue Queue 中，但不會再向 select 電路發出 request 訊號了</li>
</ul>
</li>
<li><em>Cycle n + 2</em>：
<ul>
<li>如果這條指令所需的 operands 都可獲得 (不論是來自 bypassing network 或是 PRF)，這條指令就可以被正常執行，並從 Issue Queue 中刪除該指令 (代表指令離開 Issue Queue 了)</li>
<li>如果這條指令所需的 operands 來自於前面的 load 指令，且該 load 指令發生了 D-Cache miss，那麼這條指令就沒辦法繼續被執行，需要重新”放回” Issue Queue 中並等待 D-Cache miss 被解決
<ul>
<li>實際上這條指令並沒有真的離開 Issue Queue (i.e. 還是佔著 Issue Queue 的 entry)，只需修改對應的 status bits 即可</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>浮點數的 load/store 指令也是在整數的 cluster 中被執行的</li>
</ul>
<h1 id="115---執行單元">11.5 - 執行單元</h1>
<h2 id="1151---整數的執行單元">11.5.1 - 整數的執行單元</h2>
<ul>
<li>
<p>Alpha 21264 共有 6 個 FU (4 個 Integer FU，2 個 Floating-point FU)，每個 cycle 可以同時執行六條指令</p>
<ul>
<li>i.e. Alpha 21264 是一個 machine width = 4，issue width = 6 的 superscalar CPU</li>
</ul>
</li>
<li>
<p>Alpha 21264 採用了 <a href="../superscalar-overview-ch8-part1/#812---%E6%95%B8%E6%93%9A%E6%8D%95%E6%8D%89-data-capture-vs-%E9%9D%9E%E6%95%B8%E6%93%9A%E6%8D%95%E6%8D%89-non-data-capture">non-data-capturing</a> 的架構，在指令被 select 電路選中後，才去讀 PRF</p>
<ul>
<li>Integer PRF 因此需要支持四條指令的讀取，也就是需要 8 個 read ports (假設每條指令有兩個 source registers)，導致執行速度較慢</li>
<li>為了解決這個問題，Alpha 21264 採用了 cluster 架構，將整數執行部份分為了 cluster0 和 cluster1，每個 cluster 都使用了一個完整的 Integer PRF；每個 cluster 內部又被分成了兩個 subcluster：upper (U) 以及 lower (L)
<ul>
<li>因此，每個 Integer PRF 只需 4 個 read ports，簡化了 PRF 的設計，加快執行速度</li>
</ul>
</li>
</ul>
</li>
<li>
<p>如果兩條連續的指令是在同一個 cluster 內執行，那麼就可以 back-to-back 的執行；然而如果兩條連續的指令是在不同的 clusters，如果要將一條指令的計算結果透過 bypassing network 傳給另一個 cluster 的指令，就需要跨越 cluster，經過比較長的電路，因此需要獨立使用一個 stage，導致兩條連續的指令之間會間隔一個 cycle，沒辦法 back-to-back 的執行</p>
<ul>
<li>一個 cluster 中指令執行的計算結果需要間隔一個 cycle 才能寫入另一個 cluster 的 PRF 中</li>
</ul>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%2010.png"></p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%2011.png"></p>
<ul>
<li>由於 Alpha 21264 是 out-of-order CPU，因此硬體會盡可能地找到一條不相關的指令插入間隔中，就不會降低處理器的執行效率了</li>
</ul>
</li>
</ul>
<h2 id="1152---浮點數的執行單元">11.5.2 - 浮點數的執行單元</h2>
<ul>
<li>
<p>Alpha 21264 有 2 個 Floating-point FU，每個 cycle 可以執行兩條 floating-point 指令</p>
</li>
<li>
<p>為了盡量減少連線的延遲，每個 cluster 中的 FU 都與自己的 PRF 緊靠在一起，大量地縮短 cluster 內 bypassing network 的電路，保證同一個 cluser 內連續的指令可以 back-to-back 的執行</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%2012.png"></p>
</li>
<li>
<p>Alpha 21264 同一個 cluster 內，不同指令的 latency：</p>
<table>
	<thead>
			<tr>
					<th>Instruction class</th>
					<th>Latency (cycles)</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Simple integer operations</td>
					<td>1</td>
			</tr>
			<tr>
					<td>Special instruction</td>
					<td>3</td>
			</tr>
			<tr>
					<td>Integer multiply</td>
					<td>7</td>
			</tr>
			<tr>
					<td>Integer load</td>
					<td>3 (假設 D-Cache hit)</td>
			</tr>
			<tr>
					<td>Floating-point add</td>
					<td>4</td>
			</tr>
			<tr>
					<td>Floating-point load</td>
					<td>4 (假設 D-Cache hit)</td>
			</tr>
			<tr>
					<td>Floating-point multiply</td>
					<td>4</td>
			</tr>
			<tr>
					<td>Floating-point divide</td>
					<td>12 (single-precision); 15 (double-precision)</td>
			</tr>
			<tr>
					<td>Floating-point square-root</td>
					<td>12 (single-precision); 30 (double-precision)</td>
			</tr>
	</tbody>
</table>
<ul>
<li>如果跨 cluster，則需要再增加一個 cycle</li>
</ul>
</li>
</ul>
<h1 id="116---記憶體的存取">11.6 - 記憶體的存取</h1>
<ul>
<li>Alpha 21264 的訪問記憶體元件採用了兩個特殊的設計：
<ul>
<li>能夠對 load 指令和 store 指令之間存在的 RAW 相關性進行預測，從而規劃某些 load 指令進入 pipeline 的時間，防止它們提前進入 pipeline 做白工，稱為：<code>Speculative disambiguation</code></li>
<li>能夠對 load 指令存取 D-Cache 時是否 hit 做預測，從而避免不必要的 wake up，稱為：<code>Load hit/miss Prediction</code></li>
<li>以上兩種方法本質上都是透過預測的方式來提昇處理器的執行效率，並仍然在現代處理器中被廣泛地使用</li>
</ul>
</li>
</ul>
<h2 id="1161---speculative-disambiguation">11.6.1 - Speculative Disambiguation</h2>
<ul>
<li>
<p>對於 load 指令和 store 指令來說，它們之間的相關性在 register renaming stage 是無法被解決的，只有到了 execute stage，將指令中的存取位址計算出來後，才可以判斷它們之間是否存在相關性，也就是：<code>Memory Disambiguation</code></p>
</li>
<li>
<p>Alpha 21264 採用了<a href="../superscalar-overview-ch9/#961---memory-disambiguation">完全 out-of-order</a> 的方式來執行 load 指令和 store 指令，為了最大限度地減少對 pipeline 的負面影響，Alpha 21264 還對 load 指令是否和其之前的 store 指令存在相關性進行了預測</p>
<ul>
<li>如果預測一條 load 指令和 pipeline 中還沒有 retire 的 store 指令之間不存在 RAW 相應，那麼這條 load 指令就不須等待 store 指令的存取位置被計算出來，可以直接 out-of-order 進入 execute stage 被執行，提高了執行性能</li>
</ul>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%2013.png"></p>
<ul>
<li>Alpha 21264 將對 D-Cache 的存取拆分成兩個不同的 stages (<code>D-Cache1</code>、<code>DCache2</code>)：
<ul>
<li>D-Cache1 stage：讀取 D-Cache，但這個 cycle 沒辦法得到結果</li>
<li>D-Cache2 stage：得到 data 和 tag，並比較 tag，以判斷是否 cache hit</li>
</ul>
</li>
</ul>
</li>
<li>
<p>將 D-Cache 的存取採取了 pipeline 的方式：</p>
<ul>
<li>缺點：
<ul>
<li>增加了 load 指令的執行 cycles 數</li>
<li>增加了 load 指令和與其存在相關性的指令所間隔的 cycles 數，產生更多的 bubbles</li>
</ul>
</li>
<li>優點：
<ul>
<li>可以提高 CPU 的 frequency</li>
<li>Out-of-order CPU 會盡可能地找到不相關的指令插入間隔中，因此不會對性能造成太大的負面影響</li>
</ul>
</li>
<li>因此，現代處理器基本上都使用 pipeline 的方式來存取 D-Cache</li>
</ul>
</li>
<li>
<p>在 D-Cache1 stage 中，由於 load 指令和先前的 store 指令的存取位址都已經被計算出來，因此可以檢查 load 指令是否與先前的 store 指令存在相關性，也就是：<code>disambiguation</code>，可以透過下列的硬體元件來完成：</p>
<ol>
<li><strong>Load/store Issue Queue：</strong>
<ul>
<li>以 out-of-order 的方式將 load 指令和 store 指令送到 FU 來執行</li>
</ul>
</li>
<li><strong>Load Queue：</strong>
<ul>
<li>依照 program order 的順序儲存著所有 load 指令的存取位址</li>
<li>Load 指令在 register renaming stage 就會被寫進 load queue 中 (register renaming stage 還是 in-order 的)</li>
<li>當 load 指令 retire 時，就會將 load 指令在 load queue 中對應的 entry 給釋放</li>
<li>使用 CAM 來實現，以便可以快速的比較 load 指令的存取位址</li>
</ul>
</li>
<li><strong>Store Queue：</strong>
<ul>
<li>依照 program order 的順序儲存著所有 store 指令的存取位址</li>
<li>Store 指令在 register renaming stage 就會被寫進 store queue 中 (register renaming stage 還是 in-order 的)</li>
<li>當 store 指令 retire 時，就會將 store 指令在 store queue 中對應的 entry 給釋放</li>
<li>使用 CAM 來實現，以便可以快速的比較 store 指令的存取位址</li>
</ul>
</li>
<li><strong>Wait Table：</strong>
<ul>
<li>
<p>一個 1024 x 1 bit 的表格，<strong>使用 PC address 作為索引</strong>，用來儲存 load 指令的相關性資訊</p>
</li>
<li>
<p>Wait table 中的每個 bit 都稱為：<code>Wait bit</code>，初始值皆為 <strong>0</strong>，表示所有的 load 指令和其之前的 store 指令之間都不存在相關性，可以 out-of-order execution</p>
</li>
<li>
<p>當發現了 store/load 違例，也就是發現了一條或多條在 load 指令前的 store 指令，與該 load 指令所存取的記憶體地址相同 (實際上，只要是存取範圍有重疊就存在相關性)，此時就會將該 load 指令在 wait table 中所對應的 wait bit 給設成 <strong>1</strong></p>
</li>
<li>
<p>在 decode stage，每當 decode 出一條 load 指令，就需讀取 wait table，並將 load 指令所對應的 wait bit 一起寫進 Issue Queue 中</p>
<ul>
<li>如果一條 load 指令的 wait bit 為 1，則該 load 指令必須等到所有在其之前的 store 指令都計算出存取位址後，才可以向 select 電路發出 request 請求仲裁</li>
</ul>
</li>
<li>
<p>Wait table 每 16,384 個 cycles 就會全部清為 0，以避免 wait table 的內容在經過一段時間的執行後全部變成 1 (這樣所有的 load 指令都無法 out-of-order execute 了)</p>
<ul>
<li>就算是同一條 load 指令 (i.e. PC address 相同)，也不一定每次執行時都與 store 指令仍然存在相關性</li>
</ul>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%2014.png"></p>
</li>
</ul>
</li>
</ol>
</li>
<li>
<p>指令進到 issue stage 後的下一個 cycle，進到 register read stage 並從 PRF 中讀取 operands，然後再到下一個 cycle，進到 address calculation stage 就可以計算指令的存取位址了，將存取位址計算出來後，就可以進到 D-Cache1 stage</p>
</li>
<li>
<p>在 D-Cache1 stage 會檢查 load 指令和 store 指令之間是否存在相關性，因此這個 cycle stage 也被稱為 <code>Disambiguation stage</code>，load 指令和 store 指令的 disambiguation 分別為：</p>
<ol>
<li><strong>Load Disambiguation：</strong>
<ul>
<li>Load 指令會將其存取位址寫到 <strong>load queue</strong> 對應 entry 中，同時 load 指令還會完成以下兩件事情：
<ol>
<li>Load 指令會去查詢 <strong>store queue</strong>，如果發現存在同樣存取位址且年齡比該 load 指令還<strong>老</strong>的 <strong>store 指令</strong>，那這條 load 指令就不需要存取 D-Cache 了，直接透過 store queue 就可以得到結果</li>
<li>Load 指令還需要去查詢 <strong>load queue</strong>，Alpha 21264 要求訪問相同位址的 load 指令必須是 in-order (i.e. program-order) 的，如果不滿足這個規則，在 multi-core 的環境下有可能會發生錯誤
<ul>
<li>
<p>如果發現存在存取位址相同且比該 load 指令還要<strong>年輕</strong>的 <strong>load 指令</strong>，就代表發生了 load/load 指令違例：</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%2015.png"></p>
<ul>
<li>Load 指令 X 和 load 指令 Y 執行的中間有可能被其他的 CPU 將該存取位址的值給更動了，因此如果 load 指令的執行順序改變，其結果就會出錯</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li>Alpha 21264 定義了各種記憶體存取應該保持的執行順序：
<table>
	<thead>
			<tr>
					<th>First Instruction In Pair</th>
					<th>Second Instruction in Pair</th>
					<th>Reference Order</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Load memory to address X</td>
					<td>Load memory to address X</td>
					<td>Maintained</td>
			</tr>
			<tr>
					<td>Load memory to address X</td>
					<td>Load memory to address Y</td>
					<td>Not Maintained</td>
			</tr>
			<tr>
					<td>Store memory to address X</td>
					<td>Store memory to address X</td>
					<td>Maintained</td>
			</tr>
			<tr>
					<td>Store memory to address X</td>
					<td>Store memory to address Y</td>
					<td>Maintained</td>
			</tr>
			<tr>
					<td>Load memory to address X</td>
					<td>Store memory to address X</td>
					<td>Maintained</td>
			</tr>
			<tr>
					<td>Load memory to address X</td>
					<td>Store memory to address Y</td>
					<td>Not Maintained</td>
			</tr>
			<tr>
					<td>Store memory to address X</td>
					<td>Load memory to address X</td>
					<td>Maintained</td>
			</tr>
			<tr>
					<td>Store memory to address X</td>
					<td>Load memory to address Y</td>
					<td>Not Maintained</td>
			</tr>
	</tbody>
</table>
<ul>
<li>兩條 load 指令存取同一個位址，order 必須 maintain ⇒ 否則就是 load/load 指令違例</li>
<li>Store 指令一定是 in-order 執行，因此兩條 store 指令不論存取位址是否相同，order 都必須 maintain</li>
<li>一條比較年輕的 load 指令，與一條比較老的 store 存取同一個位址，order 必須 maintain ⇒ 否則就是 store/load 指令違例</li>
<li>一條比較年輕的 store 指令，與一條比較老的 load 指令存取同一個位址，order 必須 maintain ⇒ 否則就是 store/load 指令違例</li>
<li>其他狀況，都可以 out-of-order 執行</li>
<li>Alpha 21264 中 load 指令和 store 指令是 out-of-order 執行的，因此需要在 disambiguation stage 解決順序性</li>
<li>然而，load 指令在查詢 store queue 時，如果發現存在同樣存取位址且年齡比該 load 指令還老的 store 指令，這種情況不需要 flush pipeline，因為這只代表 load 指令可以直接從 store buffer 中讀取 store 指令的資料 (需等待 store 指令執行完畢)，不需存取 D-Cache，但是 store 指令和 load 指令之間的執行仍然要保持 in-order
<ul>
<li>
<p>但如果 load 指令需要的資料寬度大於 store 指令的資料寬度 (e.g. 32-bit load vs. 8-bit store) 時，代表 load 指令所需要的資料有一部分存在 store queue 中，另外一部份存在 D-Cache 中，load 指令就沒辦法在同一個 cycle 內得到其所需的資料了</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%2016.png"></p>
<ul>
<li>此時，仍需將 load 指令和與其相關的指令都從 pipeline 中給 flush 掉，並重新從 I-Cache fetch 這些指令
<ul>
<li>在 Alpha 21264 中，這個過程稱為：<code>replay trap</code></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><strong>Store Disambiguation：</strong>
<ul>
<li>
<p>在 pipeline 的 disambiguation stage，store 指令會將其計算出來的存取位址寫到 <strong>store queue</strong> 中對應的 entry 中，並在同一個 cycle 查詢 <strong>load queue</strong>，如果發現存在同樣存取位址且年齡比該 store 指令還年輕的 load <strong>指令</strong>，則代表這條提前執行的 load 指令沒有使用到正確的計算結果，產生了 store/load 指令違例</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%2017.png"></p>
</li>
<li>
<p>當發生 store/load 指令違例時，最理想的解決方法是只將違例的 load 指令以及所有與其相關的指令從 pipeline 中給 flush 掉 (參考：<a href="../superscalar-overview-ch8-part2/#853---%E6%8E%A8%E6%B8%AC%E5%96%9A%E9%86%92">Selective Replay</a>)；然而這種設計增加了設計的複雜度，因此 Alpha 21264 採用了相對比較簡單的 replay trap 處理方法</p>
<ul>
<li>當已經離開 issue queue 的 load 指令或 store 指令由於某個原因不能再繼續執行時，這條 load 指令或 store 指令及它之後的所有指令都會從 pipeline 中被 flushed 掉，並恢復 CPU 的狀態 (Alpha 21264 有非常豐富的 checkpoints)，然後重新從 I-Cache fetch 這些指令來執行</li>
<li>Alpha 21264 中，load/load 指令違例也是採用 replay trap 的方式來處理</li>
</ul>
</li>
<li>
<p>缺點：</p>
<ul>
<li>降低了處理器的性能，如果經常發生 store/load 指令違例或是 load/load 指令違例，那麼就需要經常的 flush pipeline 中的部份指令，並重新從 I-Cache fetch 這些指令來執行
<ul>
<li>因此 Alpha 21264 才使用了 wait table 來對 store 和 load 之間的相關性進行預測，這樣可以避免大部分的 store/load 指令違例，降低需要 replay trap 的次數</li>
</ul>
</li>
</ul>
</li>
<li>
<p>當發生 store/load 指令違例後，除了進行 replay trap，還需要更新 wait table，將 load 指令在 wait table 所對應的 bit 給設成 1，這樣當下次這條違例的 load 指令再次被執行時，就需要等它之前所有的 store 指令都被 select 電路選中後，才允許這條 load 指令向 select 電路發出 request</p>
<ul>
<li>這條指令最後在執行時，有可能可以直接從 store queue 取得所需的資料</li>
</ul>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%2018.png"></p>
</li>
<li>
<p>Alpha 21264 選擇將這些被 flushed 的指令重新從 fetch stage 開始執行，而不是將違例的 load 指令及與其相關的所有指令重新放回 Issue Queue 中重新仲裁，是因為此時的 Issue Queue 可能已經沒有空間儲存這些指令了</p>
<ul>
<li>
<p>當 Issue Queue 沒有空間儲存這些指令時，這些指令就必須等待；這個等待時間可能會很長，而且需要額外一個硬體元件來儲存這些等待的指令</p>
</li>
<li>
<p>此外，由於這些指令沒辦法進入 Issue Queue，因此就不能 wake up Issue Queue 中其他的指令</p>
<ul>
<li>如果此時在 Issue Queue 中的指令正在等待這些指令來 wake up 它們，那麼在 Issue Queue 中的指令也沒辦法離開 Issue Queue，導致 Issue Queue 永遠沒有空間空出來，便會發生 <strong>dead lock</strong></li>
</ul>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%2019.png"></p>
<ul>
<li>Store 指令在 disambiguation stage 發現在其之後的 load 指令先被執行了，因此發生了 store/load 指令違例</li>
<li>為了避免 dead lock，Alpha 21264 直接將第一組和第二組的全部指令從 pipeline 中給 flush 掉，並使用 checkpoint 來恢復 CPU 的狀態，然後重新從 I-Cache fetch 這些指令來執行</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Alpha 21264 採用的 replay 方法是基於 I-Cache 的，這種方法會降低處理器的效能，如果想基於 Issue Queue 來 replay，有兩種方式可以採用：</p>
<ol>
<li>
<p>當指令被 select 電路選中時，不離開 Issue Queue，只要等到指令 retire 時才允許其離開 Issue Queue (參考：<a href="../superscalar-overview-ch8-part2/#853---%E6%8E%A8%E6%B8%AC%E5%96%9A%E9%86%92">Issue Queue Base Replay</a>)</p>
<ul>
<li>
<p>優點：</p>
<ul>
<li>設計複雜度比較低</li>
</ul>
</li>
<li>
<p>缺點：</p>
<ul>
<li>由於指令被 select 電路選中後，並不會馬上離開 Issue Queue，只有在該條指令確認可以被正確執行後 (i.e. 不需要 replay)，才會允許該條指令離開 Issue Queue；然而實際上由於 D-Cache hit rate 是很高的，且發生 store/load 指令等違例的機率並不高，所以大部分指令被 select 電路選中後，其實並不需要 replay，但這些指令仍佔據著 Issue Queue 的空間，直到確認其不需要 replay 為止，導致 Issue Queue 中實際可用的 entries 數減少
<ul>
<li>增加 Issue Queue 的空間則會增加 select 和 wake-up 電路的 latency，因此無法無上限地增加</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p>採用 <a href="../superscalar-overview-ch8-part2/#853---%E6%8E%A8%E6%B8%AC%E5%96%9A%E9%86%92">Replay Queue Based Replay</a> 的方式，增加一個 Replay Queue，用來保存離開 Issue Queue 但還沒 retire 的指令</p>
<ul>
<li>
<p>當發生 store/load 指令違例時，所有要被 replay 的指令只需從 Replay Queue 重新向 select 電路發出 request 即可</p>
<ul>
<li>Intel Pentium 4 採用了這種設計</li>
</ul>
</li>
<li>
<p>優點：</p>
<ul>
<li>提高了 Issue Queue 的使用效率</li>
</ul>
</li>
<li>
<p>缺點：</p>
<ul>
<li>Replay Queue 會佔用額外的硬體空間</li>
<li>Replay Queue 也需一起參與 select 電路的仲裁和 wake up，因此設計較複雜</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
</ul>
<h2 id="1162---load-hitmiss-prediction">11.6.2 - Load hit/miss Prediction</h2>
<ul>
<li>
<p>在 Alpha 21264 中，load 指令執行的 cycles 數是不固定的，D-Cache hit/miss、D-Cache 中是否有 bank conflict、是否和其他的元件產生 D-Cache read port conflict 等，都會影響 load 指令執行的 cycles 數；但是，如果需要等到 load 指令讀取到資料後才 wake up Issue Queue 中等待的指令，會導致 latency 過長</p>
<ul>
<li>
<p>然而，大部分的情況下 D-Cache 都會是 hit 的，因此可以直接假設 D-Cache 總是 hit 來 wake up Issue Queue 中相關的指令，也就是採用 <a href="../superscalar-overview-ch8-part2/#853---%E6%8E%A8%E6%B8%AC%E5%96%9A%E9%86%92">Speculative wake-up</a></p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%2020.png"></p>
<ul>
<li>Load 指令被 select 電路選中後，需要等待 2 個 cycles 才可以 wake up 相關的指令</li>
<li>Cycel 4、cycle 5 和 load 相關的指令就可以被 wake up 了，這兩個 cycles 也稱為：<code>Speculative Window (SW)</code>
<ul>
<li>在這兩個 cycles 被 select 電路所選中的指令都不能離開 Issue Queue (i.e. 採用 <a href="../superscalar-overview-ch8-part2/#853---%E6%8E%A8%E6%B8%AC%E5%96%9A%E9%86%92">Issue Queue Based Replay</a> 的設計)，不論它們是否真的和 load 指令存在相關性</li>
<li>當發現 load 指令真的是 D-Cache hit 時，這兩條指令就可以離開 Issue Queue</li>
<li>但如果發現 load 指令是 D-Cache miss 時，這兩條指令就必須從 pipeline 中給 flush 掉，並在 Issue Queue 中重新等待被 wake up，然後重新向 select 電路發出 request</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Alpha 21264 中並沒有區分 SW 中哪些指令和 load 指令相關，而是假設全部指令都與 load 指令相關；在發現 D-Cache miss 時會將 SW 中的所有指令從 pipeline 中給 flush 掉，並在 Issue Queue 中重新等待被 wake up，此時會假設 L2 Cache 是 hit 的，因此這些指令可以再次 (在 cycle 6 時) 被 select 電路選中，這會導致 4 個 cycles 的 latency</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%2021.png"></p>
<ul>
<li>如果 L2 Cache hit，那麼這些指令就可以從 Issue Queue 中離開</li>
<li>如果 L2 Cache miss，那麼這些指令就必須在 Issue Queue 中繼續等待</li>
</ul>
</li>
<li>
<p>在發現 D-Cache miss 時會需要將 SW 中的所有指令從 pipeline 中給 flush 掉，但這樣就浪費了執行效率，因為這些 cycles 原本可以選擇其他指令來執行</p>
<ul>
<li>為了盡量避免這種情況發生，Alpha 21264 中對 load 指令是否會 D-Cache hit 也進行了預測，只有那些預測 D-Cache hit 的 load 指令才會以 2 cycles latency 的方式來 wake up 相關的指令，否則就以 4 cycles latency (假設 L2 Cache 是 hit) 的方式來 wake up 相關的指令</li>
<li>Alpha 21264  使用了一個 <code>4-bit saturating counter</code> 來預測 load 指令是否會 D-Cache hit
<ul>
<li>每當 D-Cache hit 時，counter += 1</li>
<li>每當 D-Cache miss 時，counter -= 2</li>
<li>使用 counter 的 MSB 來作為 load 指令的預測值
<ul>
<li><code>MSB = 1</code>：預測 load 指令會 D-Cache hit</li>
<li><code>MSB = 0</code>：預測 load 指令會 D-Cache miss</li>
</ul>
</li>
</ul>
</li>
<li>在 <code>Independent Window (IW)</code> (i.e. 2 cycles latency 或是 4 cycles latency) 中可以選擇與 load 指令不相關的指令來執行，即使預測 D-Cache miss，這 4 個 cycles latency 由於仍然可以執行其他不相關的指令，因此也不會對 CPU 的性能造成太大的影響</li>
</ul>
</li>
<li>
<p>對於浮點數 load 指令來說，由於需要 128 bits 的資料，因此需要 2 個 cycles 才可以從 D-Cache 中讀出完整的結果 (64 bits x 2)，因此浮點數 load 指令的 latency 需要增加 1 個 cycle ⇒ 共 3 個 cycles</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%2022.png"></p>
<ul>
<li>此時 SW 只有 1 個 cycle (從 load 指令等待 3 個 cycles 後開始將相關的指令 wake up，直到執行時發現是否為 D-Cache hit/miss，中間所間隔的 cycles 數)
<ul>
<li>如果發現 load 指令是 D-Cache hit 時，這條指令就可以離開 Issue Queue</li>
<li>如果發現 load 指令是 D-Cache miss 時，這條指令就必須從 pipeline 中給 flush 掉，並在 Issue Queue 中重新等待被 wake up，然後重新向 select 電路發出 request</li>
</ul>
</li>
</ul>
</li>
<li>
<p>當發生 D-Cache miss 時，需要從 L2 Cache 讀取資料，浮點數 load 指令 L2 Cache hit 的 latency 同樣需要增加 1 個 cycle ⇒ 共 5 個 cycles</p>
<ul>
<li>i.e. 指令 A 可以在 cycle 7 時再次被 select 電路選中</li>
</ul>
</li>
<li>
<p>對於浮點數 load 指令來說，由於其 SW 只有 1 個 cycle，且浮點數指令執行所需的 cycles 通常都比較長，當浮點數 load 指令發生 D-Cache miss 時有足夠的時間進行處理，因此浮點數 load 指令<strong>並不會</strong>使用 saturating counter 來預測其 D-Cache 是否會 hit</p>
</li>
</ul>
<h1 id="117---退休">11.7 - 退休</h1>
<ul>
<li>在 Alpha 21264 中，一條指令要 retire 時發現了 exception，那麼在 pipeline 中的所有指令都會被 flushed 掉，這些被 flushed 的指令所佔據的 physical registers 也會被釋放，並放回 free list 中，RAT 可以透過 checkpoint 來恢復到產生 exception 那道指令之前的狀態
<ul>
<li>Alpha 21264 的 ROB 中每條指令都有一個對應的 checkpoint，80 個 ROB entries 共對應了 80 個 checkpoints，以便快速的恢復 CPU 的狀態</li>
<li>Alpha 21264 的 RAT 是<a href="../superscalar-overview-ch7/#732---%E5%9F%BA%E6%96%BC-cam-%E7%9A%84%E9%87%8D%E5%91%BD%E5%90%8D%E6%98%A0%E5%B0%84%E8%A1%A8">使用 CAM 實現</a>的，因此佔用的硬體資源也是很小的</li>
</ul>
</li>
<li>Alpha 21264 一個 cycle 內最多可以 retire 8 條指令</li>
</ul>
<h1 id="118---結論">11.8 - 結論</h1>
<ul>
<li>
<p>Alpha 21264 為了達到很高的 CPU frequency，在很多地方都加了額外的 pipeline stage，例如 對 cache 的存取；然而，這也同時增加了 mis-prediction penalty，並增大了 load latency</p>
<ul>
<li>Out-of-order execution 可以緩解 load latency 增大所引起的問題</li>
</ul>
</li>
<li>
<p>Alpha 21264 使用了複雜的分支預測方法來準確地預測分支指令，為了加快 branch mis-prediction 及 exception 發生時恢復 CPU 狀態的效率，Alpha 21264 為每個 ROB 中的每條指令都分配了一個對應的 checkpoint</p>
</li>
<li>
<p>Alpha 21264 使用了 cluster 架構來解決 multi-port PRF 所產生的問題</p>
</li>
<li>
<p>Alpha 21264 使用 load hit/miss prediction 和 speculative disambiguation 這兩種預測方法來加快 load/store 指令的執行</p>
</li>
<li>
<p>更深的 pipeline 加上更準確的預測方法，使 Alpha 21264 在運行更快的 CPU frequency 的同時，保持了較高的執行效率</p>
</li>
<li>
<p>Alpha 21264 的 pipeline：</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch11/image%2023.png"></p>
<ul>
<li>對於普通的指令，Alpha 21264 使用了 7 stages 的 pipeline</li>
<li>對於 load/store 類型的指令，由於對 D-Cache 的存取也採取了 pipeline 的方式，因此 Alpha 21264 使用了 9 stages 的 pipeline</li>
<li>對於 floating-point 類型的指令，Alpha 21264 使用了 10 stages 的 pipeline</li>
</ul>
</li>
<li>
<p>事實上，不能依 pipeline 的 stages 個數來判斷一個 CPU 的性能高低，而是還需要考慮 pipeline 的執行效率，而這需要使用更準確的各種預測方法，才能使 pipeline 保持高效率的執行</p>
</li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>&lt;超標量處理器概覽&gt; 第 7 章 - 暫存器重命名</title>
      <link>https://0xc0de.xyz/posts/superscalar-overview-ch7/</link>
      <pubDate>Thu, 27 Mar 2025 00:00:00 +0800</pubDate>
      <guid>https://0xc0de.xyz/posts/superscalar-overview-ch7/</guid>
      <description>&lt;h1 id=&#34;71---概述&#34;&gt;7.1 - 概述&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;程式中不同指令的相關性 (dependency) 可以分類為：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;數據相關性 (data dependency)，包含以下幾種類型：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;WAW (Write After Write)&lt;/code&gt; dependency，i.e. output dependence：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;兩條指令都將結果寫到同一個 destination register 中&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;WAR (Write After Read)&lt;/code&gt; dependency，i.e. anti-dependence：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一條指令的 destination register 和它前面某條指令的 source register 相同&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;RAW (Read After Write)&lt;/code&gt; dependency，i.e. true dependence：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一條指令的 source register 和它前面某條指令的 destination register 相同&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;只有 &lt;code&gt;RAW&lt;/code&gt; 是真的相關性， &lt;code&gt;WAR&lt;/code&gt; 和 &lt;code&gt;RAW&lt;/code&gt; 可以透過 register renaming 來解決&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;image.png&#34; loading=&#34;lazy&#34; src=&#34;https://0xc0de.xyz/posts/superscalar-overview-ch7/image.png&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;記憶體數據相關性 (memory data dependency)：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Load 和 store 指令之間的相關性，代表 load 和 store 指令都存取到同一個位址&lt;/li&gt;
&lt;li&gt;同樣也分為 &lt;code&gt;WAW&lt;/code&gt;、&lt;code&gt;WAR&lt;/code&gt;、&lt;code&gt;RAW&lt;/code&gt; dependencies&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;控制相關性 (control dependency)：&lt;/p&gt;</description>
      <content:encoded><![CDATA[<h1 id="71---概述">7.1 - 概述</h1>
<ul>
<li>
<p>程式中不同指令的相關性 (dependency) 可以分類為：</p>
<ol>
<li>
<p>數據相關性 (data dependency)，包含以下幾種類型：</p>
<ul>
<li>
<p><code>WAW (Write After Write)</code> dependency，i.e. output dependence：</p>
<ul>
<li>兩條指令都將結果寫到同一個 destination register 中</li>
</ul>
</li>
<li>
<p><code>WAR (Write After Read)</code> dependency，i.e. anti-dependence：</p>
<ul>
<li>一條指令的 destination register 和它前面某條指令的 source register 相同</li>
</ul>
</li>
<li>
<p><code>RAW (Read After Write)</code> dependency，i.e. true dependence：</p>
<ul>
<li>一條指令的 source register 和它前面某條指令的 destination register 相同</li>
</ul>
</li>
<li>
<p>只有 <code>RAW</code> 是真的相關性， <code>WAR</code> 和 <code>RAW</code> 可以透過 register renaming 來解決</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image.png"></p>
</li>
</ul>
</li>
<li>
<p>記憶體數據相關性 (memory data dependency)：</p>
<ul>
<li>Load 和 store 指令之間的相關性，代表 load 和 store 指令都存取到同一個位址</li>
<li>同樣也分為 <code>WAW</code>、<code>WAR</code>、<code>RAW</code> dependencies</li>
</ul>
</li>
<li>
<p>控制相關性 (control dependency)：</p>
<ul>
<li>由於分支指令所引起的相關性，可以透過分支預測來解決</li>
</ul>
</li>
<li>
<p>結構相關行 (structure dependency)：</p>
<ul>
<li>指令必須等到 CPU 中某些元件可以使用的時候才可以繼續執行
<ul>
<li>例如要等到 Issue Queue 和 ROB 中有空閒的 entry，或是 FU 計算資源是有空的</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li>
<p><code>WAW</code> 和 <code>WAR</code> dependencies 雖然可以透過 register renaming 來解決，但這兩個 dependencies 仍然存在的原因為：</p>
<ul>
<li>暫存器個數有限，導致在某些地方重複地使用暫存器
<ul>
<li>需要透過 register renaming 並引進更多的 physical registers 來彌補</li>
</ul>
</li>
<li>Loop 的存在，如果 loop body 中重複的向某個暫存器寫值，那麼就會產生大量的 <code>WAW</code> dependencies
<ul>
<li>雖然可以透過 loop unrolling 的方法來解決這個問題，但由於暫存器的個數有限，在 unloop 到某一個時刻就會把所有的暫存器給用完，此時 <code>WAW</code> dependency 就是不可避免的了</li>
<li>此外，loop unrolling 也會導致程式的 size 變大，佔用更多的記憶體空間，並導致 I-Cache miss rate 的升高</li>
</ul>
</li>
<li>Code reuse，如 recursive call；如果 function 中會向某個暫存器寫值，並被 recursively called，那麼就會產生大量的 <code>WAW</code> dependencies
<ul>
<li>同樣可以採用 inline function 的方式來解決這個問題，但也會碰到跟 loop unrolling 同樣的問題</li>
</ul>
</li>
</ul>
</li>
<li>
<p>CPU 中實際存在的暫存器個數會比指令集定義的通用暫存器的個數還來得多：</p>
<ul>
<li>CPU 內部實際存在的暫存器被稱為<strong>物理暫存器</strong> (<strong>Physical registers</strong>)</li>
<li>指令集定義的暫存器被稱為<strong>邏輯暫存器</strong> (<strong>Logical registers</strong> 或是 <strong>Architecture registers</strong>)</li>
</ul>
</li>
<li>
<p>CPU 在做 register renaming 時，會動態的將 architecture registers 映射到 physical registers，這樣可以解決 <code>WAW</code> 和 <code>WAR</code> dependencies 的問題：</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image%201.png"></p>
</li>
<li>
<p>Register renaming table (RAT)：用來保存已經存在的映射關係，i.e. architecture register → physical register)</p>
<ul>
<li>可以基於 SRAM 實現</li>
<li>也可以基於 CAM 實現</li>
<li>甚至可以採用 SRAM + CAM 來實現</li>
</ul>
</li>
<li>
<p>Free register list：用來保存目前還沒被映射的 physical registers</p>
<ul>
<li>在做 register renaming 時，會透過 free register list 來取得目前可以被映射的 physical register 編號</li>
</ul>
</li>
</ul>
<h1 id="72---暫存器重命名方式">7.2 - 暫存器重命名方式</h1>
<ul>
<li>Register renaming 有三種實做方式：
<ol>
<li>使用 <strong>ROB</strong> 來實做 register renaming</li>
<li>擴充 <strong>Architecture Register File (ARF)</strong> 來實做 register renaming</li>
<li>使用<strong>統一的 Physical Register File (PRF)</strong> 來實做 register renaming</li>
</ol>
</li>
<li>在實做 register renaming 時，一般都要考慮以下的內容：
<ol>
<li>什麼時候佔用一個 physical register? 這個 physical register 來自於哪裡?</li>
<li>什麼時候要釋放一個 physical register? 這個 physical register 要被釋放到哪裡?</li>
<li>當發生 mis-prediction 時要如何處理?</li>
<li>當發生 exception 時要如何處理?</li>
</ol>
</li>
</ul>
<h2 id="721---使用-rob-來實做暫存器重命名">7.2.1 - 使用 ROB 來實做暫存器重命名</h2>
<ul>
<li>
<p>這種方法把 ROB 當做了 physical registers，在其中儲存了<em>推測</em>的結果，而 ARF 則儲存了<em>正確</em>的結果；使用此種方法，ROB 和 ARF 都可以儲存暫存器的結果，相當於是使用了 ROB 來擴充 ARF</p>
</li>
<li>
<p>當一個指令執行完後，其計算結果會被更新到 ROB 中對應的 entry 中，但是由於有可能會發生 mis-prediction 或是 exception，因此這些暫存器的狀態為推測 (speculative) 的；該條指令在被 retired 前都會一直存在 ROB 中，直到該指令變成 pipeline 中最舊的指令，且沒有發生 mis-prediction 或 exception，才會離開 pipeline，並使用其結果更新 CPU 的狀態 (e.g. 將結果寫到 ARF 中)</p>
<ul>
<li>
<p>這種方式相當於將 PRF 和 ROB 整合了在一起：</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image%202.png"></p>
</li>
</ul>
</li>
<li>
<p>使用此方法可以簡化 register renaming 的流程，只要 ROB 中還有空間，register renaming 就可以持續地進行</p>
</li>
<li>
<p>一個 architecture register 的值有可能會同時存在 ROB 或是 ARF 中</p>
<ul>
<li>E.g. 一條指令 retire 時更新了 <code>$r1</code>，其 architecture register 的計算結果會被記錄在 ARF 中；隨後又有另外一條指令被執行，也同樣更新了 <code>$r1</code>，其 architecture register 的計算結果會被記錄在 ROB 中
<ul>
<li>
<p>因此，需要使用 RAT 來標記每個 architecture register 的計算結果是存在 ROB 或是 ARF 中：</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image%203.png"></p>
<ul>
<li>在一條指令 retire 前，其 architecture register 的計算結果會被存在 ROB 中，register renaming table 的 pointer 會指向 ROB；當這條指令 retire 時，其 architecture register 的計算結果會從 ROB 移到 ARF，RAT 的 pointer 也會一併更新指向 ARF</li>
</ul>
</li>
</ul>
</li>
<li>因為一個暫存器在它的”生命週期”內會有兩個可以被存放的位置 (ROB 或是 ARF)，這會對指令 operands 的讀取造成影響，因此在實際的 CPU 中，都會搭配 <a href="../superscalar-overview-ch8-part1/#812---%E6%95%B8%E6%93%9A%E6%8D%95%E6%8D%89-data-capture-vs-%E9%9D%9E%E6%95%B8%E6%93%9A%E6%8D%95%E6%8D%89-non-data-capture"><strong>data-capture</strong></a> 的 issue 方式，並採用 payload RAM 來儲存所需的 operands (參考：<a href="../superscalar-overview-ch10/#1031---%E4%BD%BF%E7%94%A8-rob-%E7%AE%A1%E7%90%86%E6%8C%87%E4%BB%A4%E9%9B%86%E5%AE%9A%E7%BE%A9%E7%9A%84%E7%8B%80%E6%85%8B">link</a>)
<ul>
<li>當一條指令的結果被 FU 計算出來後，會透過 bypassing network 將其結果寫進 payload RAM；Issue Queue 中所有等待這個結果的指令在被 select 電路選中時，就可以直接從 payload RAM 中得到 source registers 的值，而不用關心這些 source registers 的值是存在 ROB 或是 ARF 中</li>
</ul>
</li>
</ul>
</li>
<li>
<p>使用 ROB 做 register renaming：</p>
<ul>
<li>
<p>優點：</p>
<ul>
<li>實做容易，設計複雜度不高，且便於管理</li>
</ul>
</li>
<li>
<p>缺點：</p>
<ul>
<li>
<p>很多指令並不會更新 destination register，因此也就不用對 destination register 做 renaming，但每條指令仍然會佔用 ROB entry 中 destination register 的 physical register renaming 的空間，無法省略，浪費硬體空間</p>
</li>
<li>
<p>對於一條指令而言，它既可以從 ROB 中讀取 operands，也可以從 ARF 中讀取 operands，所以 ROB 和 ARF 最壞的情況就是一個 cycle 內，所有的指令都需要同時讀取 ROB 或 ARF，會增加 ROB 和 ARF 的 read ports 所需的數量</p>
<ul>
<li>例如：4-way issue CPU，指令最多需要 2 個 source registers，那麼 ROB 和 ARF 都需要準備 2 x 4 = 8 個 read ports，對硬體面積和延遲造成負面的影響</li>
<li>如果 CPU 有支援 multiple destination registers 的指令，那麼同樣也會對 ROB 和 ARF 的 write ports 數量造成影響</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="722---擴充-arf-來實做暫存器重命名">7.2.2 - 擴充 <strong>ARF</strong> 來實做暫存器重命名</h2>
<ul>
<li>
<p>這種方法是基於使用 ROB 來實做暫存器重命名方法的延伸；由於很多指令並沒有 destination register，例如：store 指令、分支指令和比較指令… etc，且這些指令佔了約 25% 的比例，使用 ROB 來實做暫存器重命名方法會造成 ROB 空間的浪費</p>
</li>
<li>
<p>因此，可以使用一個獨立的元件取代 ROB 來儲存 architecture register 對 physical register 的映射關係，這個元件被稱為 <strong>PRF (Physical Register File)</strong> (可以使用 FIFO 來實做)，它可以被視為 ARF 的擴充</p>
</li>
<li>
<p>在做 register renaming 時，architecture register 的計算結果被存在 PRF 中，等到這條指令 retire 時，才會將該計算結果從 PRF 搬進 ARF</p>
<ul>
<li>如果 PRF 中沒有空間了，那就必須 stall register renaming 之前的 pipeline stages，直到有指令 retire，PRF 的空間被釋放後，才可以繼續執行</li>
</ul>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image%204.png"></p>
</li>
<li>
<p>缺點：</p>
<ul>
<li>Architecture register 的計算結果仍然可能存在 PRF 及 ARF 兩個地方，因此仍然會對後面的指令使用這個暫存器作為 operands 的過程造成影響</li>
</ul>
</li>
</ul>
<h2 id="723---使用統一的-prf-來實做暫存器重命名">7.2.3 - 使用統一的 PRF 來實做暫存器重命名</h2>
<ul>
<li>
<p>這種方法將上述方法的 ARF 和 PRF 合併，合併後同樣稱為 <strong>PRF (Physical Register File)</strong>，在其中同時儲存了 speculative 和 retire 的暫存氣值</p>
</li>
<li>
<p>這種統一的 PRF，所有沒有和指令產生映射關係的暫存器都是 free 的，並會使用一個 <strong>free list</strong> (可以使用 FIFO 來實做) 來記錄目前仍為 free 狀態的 physical registers</p>
<ul>
<li>在做 register renaming 時，architecture register 的計算結果會一直被存在 PRF 中，因此在 register renaming 的過程並不需要將 architecture register 的計算結果進行搬移，方便後續的指令讀取 operands</li>
<li>這種方法同樣需要使用一個 RAT 來記錄每個 architecture register 對 physical register 的映射關係</li>
</ul>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image%205.png"></p>
</li>
<li>
<p>Superscalar CPU 在一個 cycle 內可以 retire <em>N</em> 條指令，因此每個 cycle 會有多個 physical registers 的編號會被寫進這個 FIFO 中，因此這個 FIFO 也要支援多個寫入，可以採用 interleaving 的方式來實現，避免 multi-port 的設計</p>
</li>
<li>
<p>當程式讀取暫存器時，由於很多 physical registers 仍處在 speculative 的狀態，是不能夠被程式所看到的，因此只使用一個 RAT 並沒辦法滿足這樣的要求；此時還需要使用另一個 RAT 來記錄所有 retired 的指令和 architecture register 對 physical register 的映射關係</p>
<ul>
<li>當指令 retire 時，其 architecture registers 對 physical registers 的映射關係就會被寫進這個 RAT</li>
<li>外部透過查詢這個 RAT，就可以找到 architecture register 此時對應的 physical register，避免程式讀取到 CPU 內部一些可能錯誤的狀態</li>
</ul>
</li>
<li>
<p>當一個 physical register 被佔用時，何時才可以再改為 free 狀態並加回 free list 中?</p>
<ul>
<li>
<p>當一個 physical register 不會再被後面的指令使用時，這個 physical register 就可以改為 free 狀態並加回 free list 中了</p>
<ul>
<li>i.e. 當最後一條使用到這個 physical register 的指令要被 retired 時，就可以將此 physical register 改為 free 狀態</li>
</ul>
</li>
<li>
<p>但要在 CPU 中識別這個 physical register 最後一道使用到它的指令並不是一件容易的事情，CPU 可以採用一種很簡單也很保守的方法來辨別：</p>
<ul>
<li>當一條指令和其後面的指令都寫到同一個 destination register 時，當後面的指令 retire 時，前面指令的映射關係就沒有用處了，此時就可以將前面指令的 physical register 改為 free 狀態，並加回 free list 中</li>
</ul>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image%206.png"></p>
<ul>
<li>例如：指令 (a) 和指令 (b) 都使用到了 <code>$r1</code>，如果有任何指令使用到指令 (a) 的 <code>$p1</code>，那麼這些指令一定是存在指令 (a) 和指令 (b) 之間的，因此當指令 (b) retire 時，代表不會再有任何指令會使用指令 (a) 的 <code>$p1</code>，此時便可以將 <code>$p1</code> 改為 free 狀態，並加回 free list 中了
<ul>
<li><span id="previous-physical-register-mapping-in-rob"></span>
為了實現此功能，在 <strong>ROB</strong> 中還需要記錄指令 (如指令 (b)) 的 destination register 之前所對應的 physical register (如指令 (a) 的 <code>$r1</code> 所對應的 physical register - <code>$p1</code>)，以便在指令 retire 時 (如指令 (b))，將其舊的映射關係 (<code>$r1</code> → <code>$p1</code>) 給釋放掉 (i.e. 將 <code>$p1</code> 改為 free 狀態，並加回 free list 中)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p>總結：</p>
<ul>
<li>
<p>使用 ROB 來實做 register renaming</p>
<ul>
<li>
<p>優點：</p>
<ul>
<li>Register renaming 流程簡單，在指令寫入 ROB 時，將 architecture register 和 physical register 的映射關係一併記錄到 ROB 即可，不須增加複雜的硬體控制邏輯電路</li>
</ul>
</li>
<li>
<p>缺點：</p>
<ul>
<li>暫存器的值需要被搬移 (ROB → ARF)，功耗較大</li>
<li>由於暫存器的值有可能存在 ROB 或是 ARF，當指令 retire 時，需要額外的電路同步所有有使用到該暫存器的指令來告知該暫存器已經從 ROB 搬移到 ARF，功耗較大</li>
</ul>
</li>
</ul>
</li>
<li>
<p>擴充 ARF 來實做 register renaming</p>
<ul>
<li>優點：
<ul>
<li>如同使用 ROB 來實做 register renaming，只需將 architecture register 和 physical register 的映射關係記錄到 PRF 即可，其中 PRF 可以使用 FIFO 來實做，不須增加複雜的硬體控制邏輯電路</li>
</ul>
</li>
<li>缺點：
<ul>
<li>暫存器的值需要被搬移 (PRF → ARF)，功耗較大</li>
<li>由於暫存器的值有可能存在 PRF 或是 ARF，當指令 retire 時，需要額外的電路同步所有有使用到該暫存器的指令來告知該暫存器已經從 PRF 搬移到 ARF，功耗較大</li>
</ul>
</li>
</ul>
</li>
<li>
<p>使用統一的 PRF 來實做 register renaming</p>
<ul>
<li>
<p>優點：</p>
<ul>
<li>暫存器的值只需寫入一次，不需要再被搬移，功耗較小</li>
<li>暫存器的值只會存在一個地方，不需要</li>
</ul>
</li>
<li>
<p>缺點：</p>
<ul>
<li>需要使用一個 free list 以及兩個 RAT，因此需要使用複雜的硬體控制邏輯電路</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h1 id="73---重命名映射表">7.3 - 重命名映射表</h1>
<ul>
<li>
<p>(以下皆採用統一的 PRF 來實做 register renaming 的方式)</p>
</li>
<li>
<p>RAT 的實做有以下幾種方式：</p>
<ul>
<li>基於 SRAM 來實做 (<strong>sRAT</strong>)</li>
<li>基於 CAM 來實做 (<strong>cRAT</strong>，實際上是基於 SRAM + CAM 來實做的)</li>
</ul>
</li>
<li>
<p>範例：32 個 architecture registers (<code>$r0</code> ~ <code>$r31</code>)，64 個 physical registers (<code>$p0</code> ~ <code>$p63</code>)</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image%207.png"></p>
<ul>
<li>sRAT：
<ul>
<li>使用 architecture register 來 index，共 32 個</li>
<li>每個 RAT entry 記錄了 architecture register 所對應的 physical register (共 6 bits)</li>
</ul>
</li>
<li>cRAT：
<ul>
<li>CAM 是使用<strong>內容</strong>來 index 的，CAM 會將內容與每個 entry 做比較 (類似 fully-associative cache)，並回傳與內容相符的 entry indexes</li>
<li>因此 cRAT 是透過 architecture register 來 index (共 5 bits)，CAM 會回傳與其對應的 physical register index</li>
</ul>
</li>
</ul>
</li>
<li>
<p>雖然 SRAM 的存取速度比 CAM 來得快，而且 sRAT 比 cRAT 更省空間 (architecture registers 數量都是固定的，physical register 所佔的空間只為 log2 bits)，但是在現實的 CPU 中，仍然存在使用 cRAT 的設計</p>
<ul>
<li>這是因為 cRAT 在做 checkpoint 時，<strong>只需保存 valid bits 及 free list 的 read pointer (sRAT 同樣也需保存 free list 的 read pointer)，不需將整個 cRAT 做保存</strong>，大大減少 checkpoint 所需的電路面積
<ul>
<li>因此相較於 sRAT，cRAT 不會隨著 checkpoint 的數量增加而增加大量的硬體面積
<ul>
<li>當 checkpoints 的數量超過一定值，cRAT 就比 sRAT 有更大的優勢</li>
</ul>
</li>
<li>只需保存 free list 的 read pointer：
<ul>
<li>Write pointer + 1 代表有指令 retire，將 physical register 加回 free list 中
<ul>
<li>Write pointer 在 restore checkpoint 的時候不需要恢復，因為在 checkpoint restore 時，分支指令之前的指令有可能已經 retired 了，因此我們要保留其已經 free 掉的 physical registers</li>
</ul>
</li>
<li>Read pointer + 1 代表有新的指令被執行，並使用 physical register 來映射 architecture register
<ul>
<li>Read pointer 在 checkpoint 的當下需要被保存，因為會從 free list 中拿 physical register 來建立映射關係的指令，都是分支指令之後的指令，restore checkpoint 後這些指令也需要被 flushed，因此需要恢復 read pointer</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>現代處理器通常有較深 pipeline stages 及更多的 issue ways (可以處理的指令越多，代表一個 cycle 內出現的分支指令個數有可能也會增加)，因此需要更多的 checkpoints，此時 cRAT 就是一個比較好的選擇</li>
</ul>
</li>
</ul>
<h2 id="731---基於-sram-的重命名映射表">7.3.1 - 基於 SRAM 的重命名映射表</h2>
<ul>
<li>
<p>當需要對分支指令狀態進行 checkpoint 時，需要備份整個 sRAT，因此這個實做方法每個 checkpoint 會佔用大量的硬體面積，因此限制了 checkpoints 的個數</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image%208.png"></p>
</li>
<li>
<p>對於一個 4-way 的 superscalar CPU 來說，每個 cycle 需要對 4 條指令做 register renaming，也就是 sRAT 需要支援 8 個 read ports 和 4 個 write ports (假設每條指令包含 2 個 source registers 和 1 個 destination register)；此外，還需要一個 free list 來記錄有哪些 physical registers 是 free 的</p>
</li>
<li>
<p>當有新的指令做 register renaming 時，有可能會發生 RAT entry 被蓋掉的問題，例如：</p>
<ul>
<li>此時不能直接把 RAT entry 給蓋掉，因為：
<ul>
<li>一條指令在 retire 時，要將其對應的 physical registers 改為 free 狀態，並加回 free list 中，如果其 RAT entry 被覆蓋，就沒辦法更新 physical register
<ul>
<li>例如：當發生 <code>WAW</code> 時，前後指令同樣的 destination register 會對應到不同的 physical registers，此時前面指令的 RAT entry 就會被後面指令的 RAT entry 給覆蓋</li>
</ul>
</li>
<li>當一條指令在 exception 或是 mis-prediction 的路徑上，這條指令最終會需要被 flushed 掉，同時也需要將該指令對 RAT 的修改給復原
<ul>
<li>如果舊的映射關係沒有被保存下來，就無法將該指令對 RAT 的修改給復原</li>
</ul>
</li>
</ul>
</li>
<li>因此，在一個 destination register 對 physical register 的映射關係被寫進 RAT 前，需要將其所覆蓋的 RAT entry (i.e. 舊的映射關係) 給寫進 <strong>ROB</strong> 中</li>
</ul>
</li>
<li>
<p>sRAT 相較于 cRAT，讀寫速度會快一點，設計複雜度也不會隨著 physical registers 的增加而變大，但其最大的缺點就是：<strong>Checkpoints 的數量有上限</strong></p>
<ul>
<li>但隨著處理器的並行度的提高，會有更多的分支指令存在 pipeline 中，也就需要使用更多個 checkpoints</li>
<li>不過當分支指令的預測正確時，checkpoint 是不會被使用的
<ul>
<li>因此可以對分支指令的預測正確度也進行預測，對於那些預測準確度很高的分支指令，可以不使用 checkpoint，可以把 sRAT 的 checkpoints 留給那些預測準確度較低的分支指令</li>
<li>但當這些未使用 checkpoint 的分支指令發生 mis-prediction 時，就需要使用速度較慢的方式來恢復 RAT
<ul>
<li>如果發生頻率的很低，就不會對性能造成影響</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="732---基於-cam-的重命名映射表">7.3.2 - 基於 CAM 的重命名映射表</h2>
<ul>
<li>
<p>在 cRAT 中，architecture register 就是每個 CAM entry 所保存的內容，physical register 則是最後的結果</p>
</li>
<li>
<p>cRAT 使用 architecture register 來索引 CAM，所有的 CAM entries 都會與欲索引的 architecture register 做比較，只有 CAM entry 內容與欲索引的 architecture register 相同時，其所對應的 physical register 才會被回傳；由於一個 architecture register 只會有一個對應的 physical register，因此只會有一個 CAM entry 相符</p>
<ul>
<li>相符的 entry 可以用 valid bit 來表示，i.e. <code>V = 1</code></li>
</ul>
</li>
<li>
<p>對 cRAT 做 checkpoint 時，只需 checkpoint valid bits 即可</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image%209.png"></p>
</li>
<li>
<p>由於 cRAT 所需的 checkpoint 資源很少，因此可以將 checkpoints 個數做得很大</p>
<ul>
<li>E.g. Alpha 21264 使用 cRAT 做 register renaming，總共包含了 80 個 checkpoints，也就是最大允許 80 條分支指令存在 pipeline 中</li>
</ul>
</li>
<li>
<p>對於一個 4-way superscalar CPU 而言，使用 cRAT：</p>
<ul>
<li>cRAT 需要支援 8 個 read ports (2 source registers * 4) 及 4 個 write ports (4 destination registers)</li>
</ul>
</li>
<li>
<p>基於 cRAT 進行 register renaming 仍然需要使用 free list 來記錄哪幾個 physical registers 是 free 狀態的</p>
<ul>
<li>要等指令 retire 時，才可以將其 architecture register 所對應的 physical register 改為 free 狀態並加回 free list 中</li>
<li>因此，在 cRAT 中，並不是一個 physical register 的 valid bit 為 0 時，就代表其為 free 狀態，有可能是其映射關係剛被覆蓋而已
<ul>
<li>
<p>例如：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-2">2</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-asm" data-lang="asm"><span style="display:flex;"><span><span style="color:#a6e22e">addi</span> <span style="color:#66d9ef">$r7</span>, <span style="color:#66d9ef">$r0</span>, <span style="color:#ae81ff">2</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">addi</span> <span style="color:#66d9ef">$r7</span>, <span style="color:#66d9ef">$r3</span>, <span style="color:#ae81ff">3</span>
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>第一條指令：<code>$p11</code> → <code>$r7</code> ⇒ <code>V = 1</code></li>
<li>第二條指令： <code>$p12</code> → <code>$r7</code> ⇒ <code>V = 1</code>；<code>$p11</code> → <code>$r7</code> ⇒ <code>V = 1</code> → <code>0</code>
<ul>
<li><code>$p11</code> → <code>$r7</code> 的映射關係被 <code>$p12</code> → <code>$r7</code> 取代，因此 <code>V = 1</code> → <code>0</code>，但不代表 <code>$p11</code> 就是 free 狀態的</li>
</ul>
</li>
</ul>
</li>
<li>
<p>指令實際在 pipeline 中的運算還是使用<strong>當初所被分配的 physical register</strong>，所以只有等到指令 retire 後，其 physical register 才可以被改為 free 狀態</p>
<ul>
<li>i.e. 第一條指令 <code>$r7</code> 所使用的 physical register 依然是 <code>$p11</code>，RAT 只是記錄<strong>最新的映射狀態</strong></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p>當一條指令 retire，其 physical register 改為 <strong>free 狀態</strong>後，該 physical register 在 RAT 中的映射關係的 <strong>valid bit 也會被設為 0</strong></p>
<ul>
<li>也就是說，<code>V = 0</code> 同時表示了：
<ul>
<li>映射關係被取代</li>
<li>Physical register 已經被改為 free 狀態</li>
</ul>
</li>
</ul>
</li>
<li>
<p>cRAT checkpoint &amp; restore 範例 (只針對 destination register 的部份)：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-1-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-1-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-1-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-1-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-4">4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-1-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-5">5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-1-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-6">6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-1-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-7">7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-1-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-8">8</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-asm" data-lang="asm"><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">指令</span> <span style="color:#a6e22e">A</span><span style="color:#960050;background-color:#1e0010">：</span><span style="color:#66d9ef">addi</span> <span style="color:#66d9ef">$r5</span>, <span style="color:#66d9ef">$r0</span>, <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">指令</span> <span style="color:#a6e22e">B</span><span style="color:#960050;background-color:#1e0010">：</span><span style="color:#66d9ef">addi</span> <span style="color:#66d9ef">$r7</span>, <span style="color:#66d9ef">$r0</span>, <span style="color:#ae81ff">2</span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">指令</span> <span style="color:#a6e22e">C</span><span style="color:#960050;background-color:#1e0010">：</span><span style="color:#66d9ef">addi</span> <span style="color:#66d9ef">$r6</span>, <span style="color:#66d9ef">$r7</span>, <span style="color:#ae81ff">3</span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">指令</span> <span style="color:#a6e22e">D</span><span style="color:#960050;background-color:#1e0010">：</span><span style="color:#66d9ef">add</span>  <span style="color:#66d9ef">$r7</span>, <span style="color:#66d9ef">$r7</span>, <span style="color:#66d9ef">$r1</span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">指令</span> <span style="color:#a6e22e">E</span><span style="color:#960050;background-color:#1e0010">：</span><span style="color:#66d9ef">add</span>  <span style="color:#66d9ef">$r7</span>, <span style="color:#66d9ef">$r7</span>, <span style="color:#66d9ef">$r2</span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">指令</span> <span style="color:#a6e22e">F</span><span style="color:#960050;background-color:#1e0010">：</span><span style="color:#66d9ef">beq</span>  <span style="color:#66d9ef">$r7</span>, <span style="color:#66d9ef">$r3</span>, <span style="color:#75715e">#TARGET1
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">指令</span> <span style="color:#a6e22e">G</span><span style="color:#960050;background-color:#1e0010">：</span><span style="color:#66d9ef">add</span>  <span style="color:#66d9ef">$r9</span>, <span style="color:#66d9ef">$r5</span>, <span style="color:#66d9ef">$r6</span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">指令</span> <span style="color:#a6e22e">H</span><span style="color:#960050;background-color:#1e0010">：</span><span style="color:#66d9ef">add</span>  <span style="color:#66d9ef">$r5</span>, <span style="color:#66d9ef">$r9</span>, <span style="color:#66d9ef">$r9</span>
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>
<p>當分支指令 F 做 register renaming 時，需要對 cRAT 做 checkpoint，此時 cRAT 的內容如下：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-15">15</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-16">16</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-17"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-17">17</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-18"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-18">18</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-19"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-19">19</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-20"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-20">20</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-21"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-21">21</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-22"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-22">22</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-23"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-23">23</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-24"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-24">24</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-25"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-25">25</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-26"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-26">26</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-27"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-27">27</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-28"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-28">28</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-29"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-29">29</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>+--------------------------------------------+-------------------------------+
</span></span><span style="display:flex;"><span>|                   cRAT                     |          Checkpoints          |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|  Inst   |  Phys Regs  | Arch Reg  |   V    |  GC0  |  GC1  |  GC2  |  GC3  |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p0      |           |        |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|   ...   |     ...     |    ...    |  ...   |  ...  |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    A    |    $p10     |    $r5    |   1    |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    B    |    $p11     |    $r7    | 1 -&gt; 0 |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    C    |    $p12     |    $r6    |   1    |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    D    |    $p13     |    $r7    | 1 -&gt; 0 |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    E    |    $p14     |    $r7    |   1    |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p15     |           |        |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p16     |           |        |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p17     |           |        |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |     ...     |           |        |  ...  |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p63     |           |        |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>當指令 D 做 register renaming 時，由於指令 D 和指令 B 都存取 <code>$r7</code>，因此指令 B 的映射關係會被 invalid (<code>V = 0</code>)</li>
<li>當指令 E 做 register renaming 時，由於指令 E 和指令 D 都存取 <code>$r7</code>，因此指令 D 的映射關係會被 invalid (<code>V = 0</code>)</li>
<li>分支指令 F 做 register renaming 時：
<ul>
<li>Checkpoint - GC0 的內容會被更新為：<code>1</code>, <code>0</code>, <code>1</code>, <code>0</code>, <code>1</code></li>
</ul>
</li>
</ul>
</li>
<li>
<p>在指令 G、指令 H 也做完 register renaming 後，指令 F 發生 mis-prediction，因此需要使用 GC0 來恢復 cRAT；在使用 GC0 來恢復前的 cRAT 內容如下：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-15">15</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-16">16</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-17"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-17">17</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-18"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-18">18</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-19"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-19">19</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-20"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-20">20</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-21"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-21">21</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-22"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-22">22</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-23"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-23">23</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-24"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-24">24</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-25"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-25">25</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-26"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-26">26</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-27"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-27">27</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-28"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-28">28</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-29"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-29">29</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>+--------------------------------------------+-------------------------------+
</span></span><span style="display:flex;"><span>|                   cRAT                     |          Checkpoints          |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|  Inst   |  Phys Regs  | Arch Reg  |   V    |  GC0  |  GC1  |  GC2  |  GC3  |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p0      |           |        |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|   ...   |     ...     |    ...    |  ...   |  ...  |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    A    |    $p10     |    $r5    |   1    |   1   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    B    |    $p11     |    $r7    | 1 -&gt; 0 |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    C    |    $p12     |    $r6    |   1    |   1   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    D    |    $p13     |    $r7    | 1 -&gt; 0 |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    E    |    $p14     |    $r7    | 1 -&gt; 0 |   1   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    G    |    $p15     |    $r9    |   0    |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    H    |    $p16     |    Rr7    |   1    |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p17     |           |        |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    ...      |           |        |  ...  |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p63     |           |        |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>當指令 H 做 register renaming 時，由於指令 H 和指令 E 都存取 <code>$r7</code>，因此指令 E 的映射關係會被 invalid (<code>V = 0</code>)</li>
<li>當恢復 GC0 後，<code>$p10</code> ~ <code>$p16</code> 的 <code>V</code> 值會被恢復成：<code>1</code>, <code>0</code>, <code>1</code>, <code>0</code>, <code>1</code>, <code>0</code>, <code>0</code>
<ul>
<li>在分支指令 F 之前的指令有可能在恢復 checkpoint - GC0 的當下已經 retired 了，此時有以下可能：
<ul>
<li>Physical register 改為 free 狀態，並加入 free list 中 ⇒ <code>V = 0</code>
<ul>
<li><code>V</code> 被 restored 回 <code>0</code> (如指令 B)
<ul>
<li>不會造成影響，因為本來 <code>V = 0</code> 本來也就可以表示 free 狀態</li>
</ul>
</li>
<li><code>V</code> 被 restored 回 <code>1</code> (如指令 C)
<ul>
<li>被恢復的指令已經 retired 了，其 physical register 已經被加入 free list 中，因此只要在存取 RAT 時有一併檢查 physical register 是否在 free list 中，就算 <code>V</code> 被 restored 回 <code>1</code> 也沒關係</li>
</ul>
</li>
</ul>
</li>
<li>Physical register 被其他指令重新映射 ⇒ <code>V = 1</code>
<ul>
<li><code>V</code> 被 restored 回 <code>0</code> (如指令 B)
<ul>
<li>不會造成影響，因為重新映射的指令是分支指令之後的指令，本來就應該被 flushed 掉 ⇒ <code>V = 0</code></li>
</ul>
</li>
<li><code>V</code> 被 restored 回 <code>1</code> (如指令 C)
<ul>
<li>重新映射的指令也應該被 flushed ⇒ <code>V = 0</code>，不過由於被恢復的指令已經 retired 了，其 physical register 已經被加入 free list 中，因此只要在存取 RAT 時有一併檢查 physical register 是否在 free list 中，就算 <code>V</code> 被 restored 回 <code>1</code> 也沒關係</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p>一般情況下，pipeline 中允許存在的最多的分支指令數，和處理器最大可以支援的 checkpoints 數量是一樣的 (假設只有分支指令使用 checkpoint)</p>
</li>
<li>
<p>如果分支預測正確，就可以將分支指令對應的 checkpoint 給釋放掉，變成 free 狀態，後續分支指令可以繼續使用它</p>
</li>
<li>
<p>分支預測失敗，restore checkpoint 後，也會一併將該 checkpoint 給釋放掉，變成 free 狀態，後續分支指令也可以繼續使用它</p>
</li>
<li>
<p>cRAT checkpoint &amp; restore 兩條分支指令範例 (只針對 destination register 的部份)：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-10">10</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-asm" data-lang="asm"><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">指令</span> <span style="color:#a6e22e">A</span><span style="color:#960050;background-color:#1e0010">：</span><span style="color:#66d9ef">addi</span> <span style="color:#66d9ef">$r7</span>, <span style="color:#66d9ef">$r0</span>, <span style="color:#ae81ff">3</span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">指令</span> <span style="color:#a6e22e">B</span><span style="color:#960050;background-color:#1e0010">：</span><span style="color:#66d9ef">add</span>  <span style="color:#66d9ef">$r6</span>, <span style="color:#66d9ef">$r7</span>, <span style="color:#66d9ef">$r1</span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">指令</span> <span style="color:#a6e22e">C</span><span style="color:#960050;background-color:#1e0010">：</span><span style="color:#66d9ef">add</span>  <span style="color:#66d9ef">$r7</span>, <span style="color:#66d9ef">$r7</span>, <span style="color:#66d9ef">$r2</span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">指令</span> <span style="color:#a6e22e">D</span><span style="color:#960050;background-color:#1e0010">：</span><span style="color:#66d9ef">beq</span>  <span style="color:#66d9ef">$r7</span>, <span style="color:#66d9ef">$r3</span>, <span style="color:#75715e">#TARGET1
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">指令</span> <span style="color:#a6e22e">E</span><span style="color:#960050;background-color:#1e0010">：</span><span style="color:#66d9ef">add</span>  <span style="color:#66d9ef">$r9</span>, <span style="color:#66d9ef">$r5</span>, <span style="color:#66d9ef">$r6</span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">指令</span> <span style="color:#a6e22e">F</span><span style="color:#960050;background-color:#1e0010">：</span><span style="color:#66d9ef">add</span>  <span style="color:#66d9ef">$r9</span>, <span style="color:#66d9ef">$r9</span>, <span style="color:#66d9ef">$r8</span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">指令</span> <span style="color:#a6e22e">G</span><span style="color:#960050;background-color:#1e0010">：</span><span style="color:#66d9ef">beq</span>  <span style="color:#66d9ef">$r9</span>, <span style="color:#66d9ef">$r3</span>, <span style="color:#75715e">#TARGET2
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">指令</span> <span style="color:#a6e22e">H</span><span style="color:#960050;background-color:#1e0010">：</span><span style="color:#66d9ef">addi</span> <span style="color:#66d9ef">$r7</span>, <span style="color:#66d9ef">$r0</span>, <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">指令</span> <span style="color:#a6e22e">H</span><span style="color:#960050;background-color:#1e0010">：</span><span style="color:#66d9ef">addi</span> <span style="color:#66d9ef">$r6</span>, <span style="color:#66d9ef">$r0</span>, <span style="color:#ae81ff">2</span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">指令</span> <span style="color:#a6e22e">H</span><span style="color:#960050;background-color:#1e0010">：</span><span style="color:#66d9ef">sub</span>  <span style="color:#66d9ef">$r9</span>, <span style="color:#66d9ef">$r1</span>, <span style="color:#66d9ef">$r0</span>
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>
<p>當分支指令 D 做 register renaming 時，需要對 cRAT 做 checkpoint，此時 cRAT 的內容如下：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-15">15</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-16">16</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-17"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-17">17</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-18"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-18">18</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-19"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-19">19</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-20"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-20">20</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-21"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-21">21</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-22"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-22">22</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-23"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-23">23</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-24"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-24">24</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-25"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-25">25</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-26"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-26">26</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-27"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-27">27</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-28"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-28">28</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-29"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-29">29</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>+--------------------------------------------+-------------------------------+
</span></span><span style="display:flex;"><span>|                   cRAT                     |          Checkpoints          |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|  Inst   |  Phys Regs  | Arch Reg  |   V    |  GC0  |  GC1  |  GC2  |  GC3  |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p0      |           |        |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|   ...   |     ...     |    ...    |  ...   |  ...  |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    A    |    $p10     |    $r7    | 1 -&gt; 0 |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    B    |    $p11     |    $r6    |   1    |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    C    |    $p12     |    $r7    |   1    |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p13     |           |        |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p14     |           |        |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p15     |           |        |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p16     |           |        |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p17     |           |        |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |     ...     |           |        |  ...  |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p63     |           |        |   0   |       |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>當指令 C 做 register renaming 時，由於指令 C 和指令 A 都存取 <code>$r7</code>，因此指令 A 的映射關係會被 invalid (<code>V = 0</code>)</li>
<li>分支指令 D 做 register renaming 時：
<ul>
<li>Checkpoint - GC0 的內容會被更新為：<code>0</code>, <code>1</code>, <code>1</code></li>
</ul>
</li>
</ul>
</li>
<li>
<p>當分支指令 G 做 register renaming 時，需要對 cRAT 做 checkpoint，此時 cRAT 的內容如下：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-15">15</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-16">16</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-17"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-17">17</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-18"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-18">18</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-19"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-19">19</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-20"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-20">20</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-21"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-21">21</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-22"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-22">22</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-23"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-23">23</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-24"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-24">24</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-25"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-25">25</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-26"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-26">26</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-27"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-27">27</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-28"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-28">28</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-29"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-29">29</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>+--------------------------------------------+-------------------------------+
</span></span><span style="display:flex;"><span>|                   cRAT                     |          Checkpoints          |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|  Inst   |  Phys Regs  | Arch Reg  |   V    |  GC0  |  GC1  |  GC2  |  GC3  |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p0      |           |        |   0   |   0   |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|   ...   |     ...     |    ...    |  ...   |  ...  |  ...  |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    A    |    $p10     |    $r7    | 1 -&gt; 0 |   0   |   0   |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    B    |    $p11     |    $r6    |   1    |   1   |   0   |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    C    |    $p12     |    $r7    |   1    |   1   |   0   |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    E    |    $p13     |    $r9    | 1 -&gt; 0 |   0   |   0   |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    F    |    $p14     |    $r9    |   1    |   0   |   0   |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p15     |           |        |   0   |   0   |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p16     |           |        |   0   |   0   |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p17     |           |        |   0   |   0   |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |     ...     |           |        |  ...  |  ...  |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p63     |           |        |   0   |   0   |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>當指令 F 做 register renaming 時，由於指令 F 和指令 E 都存取 <code>$r9</code>，因此指令 E 的映射關係會被 invalid (<code>V = 0</code>)</li>
<li>分支指令 G 做 register renaming 時：
<ul>
<li>Checkpoint - GC1 的內容會被更新為：<code>0</code>, <code>1</code>, <code>1</code>, <code>0</code>, <code>1</code></li>
</ul>
</li>
</ul>
</li>
<li>
<p>當所有指令都完成 register renaming 後，cRAT 的內容如下：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-15">15</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-16">16</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-17"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-17">17</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-18"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-18">18</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-19"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-19">19</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-20"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-20">20</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-21"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-21">21</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-22"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-22">22</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-23"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-23">23</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-24"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-24">24</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-25"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-25">25</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-26"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-26">26</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-27"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-27">27</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-28"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-28">28</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-29"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-29">29</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>+--------------------------------------------+-------------------------------+
</span></span><span style="display:flex;"><span>|                   cRAT                     |          Checkpoints          |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|  Inst   |  Phys Regs  | Arch Reg  |   V    |  GC0  |  GC1  |  GC2  |  GC3  |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p0      |           |        |   0   |   0   |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|   ...   |     ...     |    ...    |  ...   |  ...  |  ...  |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    A    |    $p10     |    $r7    | 1 -&gt; 0 |   0   |   0   |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    B    |    $p11     |    $r6    | 1 -&gt; 0 |   1   |   1   |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    C    |    $p12     |    $r7    | 1 -&gt; 0 |   1   |   1   |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    E    |    $p13     |    $r9    | 1 -&gt; 0 |   0   |   0   |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    F    |    $p14     |    $r9    | 1 -&gt; 0 |   0   |   1   |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    H    |    $p15     |    $r7    |   1    |   0   |   0   |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    I    |    $p16     |    $r6    |   1    |   0   |   0   |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|    J    |    $p17     |    $r9    |   1    |   0   |   0   |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |     ...     |           |        |  ...  |  ...  |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span><span style="display:flex;"><span>|         |    $p63     |           |        |   0   |   0   |       |       |
</span></span><span style="display:flex;"><span>+---------+-------------+-----------+--------+-------+-------+-------+-------+
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>當指令 H 做 register renaming 時，由於指令 H 和指令 C 都存取 <code>$r7</code>，因此指令 C 的映射關係會被 invalid (<code>V = 0</code>)</li>
<li>當指令 I 做 register renaming 時，由於指令 I 和指令 B 都存取 <code>$r6</code>，因此指令 B 的映射關係會被 invalid (<code>V = 0</code>)</li>
<li>當指令 J 做 register renaming 時，由於指令 J 和指令 F 都存取 <code>$r9</code>，因此指令 F 的映射關係會被 invalid (<code>V = 0</code>)</li>
</ul>
</li>
<li>
<p>如果指令 D 發生 mis-prediction，就需要使用 GC0 來恢復 cRAT，並在恢復完 cRAT 後將 GC0 給釋放掉</p>
<ul>
<li>如果是 in-order core，則在 restore checkpoint 時，分支指令一定會是最後一條指令，GC1 一定會是在 mis-prediction 的路徑上，因此 GC1 也可以被釋放掉</li>
</ul>
</li>
<li>
<p>如果指令 D 預測正確，但指令 G 發生 mis-prediction，就需要使用 GC1 來恢復 cRAT，並在恢復完 cRAT 後將 GC1 給釋放掉</p>
</li>
<li>
<p>cRAT 並不負責管理哪些 physical registers 是 free 狀態的，這個功能是透過 ROB 和 free list 來實現的</p>
</li>
<li>
<p>基於 CAM 的重命名映射表最大的弊端就是其硬體面積會隨著 CPU 中 physical registers 的個數增大而變大，因為 CAM 的 entry 個數，就是 physical registers 的個數</p>
<ul>
<li>隨著處理器並行度的增加，需要更多的 physical registers，此時 cRAT 就需要更多的比較電路，進而拖慢 CPU 的速度</li>
<li>但是由於 cRAT checkpoint 時只需保存 valid bits (以及 free list 的 read pointer) 即可，大大降低了對硬體的需求，尤其是現在處理器中，會有更多的指令在 pipeline 中，需要更多的 checkpoints 配合，這時 cRAT 的優勢就體現出來了</li>
<li>因此在設計時需要權衡使用 cRAT 的優缺點</li>
</ul>
</li>
</ul>
</li>
</ul>
<h1 id="74---超標量處理器的暫存器重命名">7.4 - 超標量處理器的暫存器重命名</h1>
<ul>
<li>
<p>RAT 在初始化時，architecture registers 就已經有對應的 physical registers，因此 source register 可以直接讀取 RAT 取得對應的 physical register，例如：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-4">4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-5">5</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>$r0 -&gt; $p0
</span></span><span style="display:flex;"><span>$r1 -&gt; $p1
</span></span><span style="display:flex;"><span>$r2 -&gt; $p1
</span></span><span style="display:flex;"><span>...
</span></span><span style="display:flex;"><span>$r31 -&gt; $p31
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>剩餘沒映射關係的 physical registers 會被加進 free list 中</li>
</ul>
</li>
<li>
<p>對於一條：<code>Dest = Src1 op Src2</code> 的指令，register renaming 的過程如下：</p>
<ol>
<li>
<p>從 RAT 找到 <code>Src1</code> 和 <code>Src2</code> 對應的 physical registers：<code>Psrc1</code>、<code>Psrc2</code></p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image%2010.png"></p>
</li>
<li>
<p>從 free list 中找到一個 free 狀態的 physical register：<code>Pdest</code></p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image%2011.png"></p>
</li>
<li>
<p>將 <code>Dest</code> → <code>Pdest</code> 的映射寫進 RAT 中</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image%2012.png"></p>
</li>
</ol>
</li>
<li>
<p>由上述範例可以知道：</p>
<ul>
<li>
<p>RAT 需要支援 2 個 read ports (source registers) 和 1 個 write port (destination register)</p>
</li>
<li>
<p>(對於 sRAT) 為了將 physical register 釋放回 free list，因此還需要將每條指令之前的對應關係保存到 ROB 中 (參考：<a href="#previous-physical-register-mapping-in-rob">link</a>)，因此 RAT 還需要 1 個額外的 read port 來讀取 destination register 所對應的 physical register</p>
</li>
<li>
<p>對於 superscalar CPU 而言，N-way CPU 的 RAT 就提供 N 倍的 read ports 和 write ports：</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image%2013.png"></p>
</li>
</ul>
</li>
<li>
<p>除了 multi-port RAT 外，register renaming 還需考慮到每個 cycle 同時 rename 多條指令之間所存在的 dependencies，例如：</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image%2014.png"></p>
<ul>
<li>指令 A 和指令 B 有 <code>RAW</code> dependency
<ul>
<li>為 true dependency</li>
</ul>
</li>
<li>指令 A 、指令 B 和指令 D 有 <code>WAW</code> dependency
<ul>
<li>可以透過 register renaming 解決，但實際上仍無法忽略其存在：
<ol>
<li>
<p>在一個 cycle 內多條指令發生 <code>WAW</code>，只需將最新那條指令的映射關係寫進 RAT 即可</p>
<ul>
<li>舊的指令還是會被分配 physical registers，後續在 pipeline 中的運算也是使用被分配的 physical registers，只是不需要將其映射關係給寫進 RAT，不然只是浪費 RAT 的空間</li>
</ul>
</li>
<li>
<p>在將每條指令的舊映射關係寫進 ROB 時，如果發現一個 cycle 內有多條指令都使用同一個 destination register，那麼此時寫進 ROB 的舊映射關係，就不是來自 RAT，而是來自於與其發生 <code>WAW</code> 的那條指令 (參考：<a href="#previous-physical-register-mapping-in-rob">link</a>)</p>
<ul>
<li>例如：
<ul>
<li>指令 B 的 <code>$r0</code> → <code>$p31</code>，<code>$r0</code> 舊的映射關係是來自指令 A 的 <code>$p30</code>，而不是來自於 RAT 所讀出的結果</li>
<li>指令 D 的 <code>$r0</code> → <code>$p33</code>，<code>$r0</code> 舊的映射關係是來自指令 B 的 <code>$p31</code>，而不是來自於 RAT 所讀出的結果</li>
</ul>
</li>
<li>因此 superscalar CPU 在做 register renaming 時，仍需對指令間的 <code>WAW</code> dependency 做檢查</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
<li>指令 B 和指令 D 有 <code>WAR</code> dependency
<ul>
<li>可以透過 register renaming 解決</li>
</ul>
</li>
</ul>
</li>
<li>
<p>因此，superscalar CPU 在做 register renaming 時，需檢查 <code>RAW</code> 和 <code>WAW</code> 的 dependencies</p>
</li>
</ul>
<h2 id="741---解決-raw-相關性">7.4.1 - 解決 RAW 相關性</h2>
<ul>
<li>
<p>對 4-way superscalar CPU 來說，每個 cycle 可以處理 4 條指令，如果這 4 條指令之間不存在 RAW，則 register renaming 過程就相對單純，例如：</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image%2015.png"></p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-4">4</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-asm" data-lang="asm"><span style="display:flex;"><span><span style="color:#a6e22e">$r1</span> <span style="color:#960050;background-color:#1e0010">=</span> <span style="color:#66d9ef">$r1</span> <span style="color:#960050;background-color:#1e0010">+</span> <span style="color:#66d9ef">$r2</span>    <span style="color:#960050;background-color:#1e0010">=&gt;</span> <span style="color:#66d9ef">$p31</span> <span style="color:#960050;background-color:#1e0010">=</span> <span style="color:#66d9ef">$p10</span> <span style="color:#960050;background-color:#1e0010">+</span> <span style="color:#66d9ef">$p11</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">$r3</span> <span style="color:#960050;background-color:#1e0010">=</span> <span style="color:#66d9ef">$r3</span> <span style="color:#960050;background-color:#1e0010">+</span> <span style="color:#66d9ef">$r4</span>    <span style="color:#960050;background-color:#1e0010">=&gt;</span> <span style="color:#66d9ef">$p40</span> <span style="color:#960050;background-color:#1e0010">=</span> <span style="color:#66d9ef">$p12</span> <span style="color:#960050;background-color:#1e0010">+</span> <span style="color:#66d9ef">$p13</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">$r5</span> <span style="color:#960050;background-color:#1e0010">=</span> <span style="color:#66d9ef">$r6</span> <span style="color:#66d9ef">x</span> <span style="color:#66d9ef">$r7</span>    <span style="color:#960050;background-color:#1e0010">=&gt;</span> <span style="color:#66d9ef">$p8</span>  <span style="color:#960050;background-color:#1e0010">=</span> <span style="color:#66d9ef">$p20</span> <span style="color:#66d9ef">x</span> <span style="color:#66d9ef">$p21</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">$r8</span> <span style="color:#960050;background-color:#1e0010">=</span> <span style="color:#66d9ef">Load</span> <span style="color:#ae81ff">9</span>[<span style="color:#66d9ef">$r9</span>]  <span style="color:#960050;background-color:#1e0010">=&gt;</span> <span style="color:#66d9ef">$p5</span>  <span style="color:#960050;background-color:#1e0010">=</span> <span style="color:#66d9ef">Load</span> <span style="color:#ae81ff">9</span>[<span style="color:#66d9ef">$p22</span>]
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>但當這 4 條指令有 RAW 時：</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image%2016.png"></p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-4">4</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-asm" data-lang="asm"><span style="display:flex;"><span><span style="color:#a6e22e">$r1</span> <span style="color:#960050;background-color:#1e0010">=</span> <span style="color:#66d9ef">$r1</span> <span style="color:#960050;background-color:#1e0010">+</span> <span style="color:#66d9ef">$r2</span>    <span style="color:#960050;background-color:#1e0010">=&gt;</span> <span style="color:#66d9ef">$p31</span> <span style="color:#960050;background-color:#1e0010">=</span> <span style="color:#66d9ef">$p10</span> <span style="color:#960050;background-color:#1e0010">+</span> <span style="color:#66d9ef">$p11</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">$r3</span> <span style="color:#960050;background-color:#1e0010">=</span> <span style="color:#66d9ef">$r3</span> <span style="color:#960050;background-color:#1e0010">+</span> <span style="color:#66d9ef">$r4</span>    <span style="color:#960050;background-color:#1e0010">=&gt;</span> <span style="color:#66d9ef">$p40</span> <span style="color:#960050;background-color:#1e0010">=</span> <span style="color:#66d9ef">$p12</span> <span style="color:#960050;background-color:#1e0010">+</span> <span style="color:#66d9ef">$p13</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">$r5</span> <span style="color:#960050;background-color:#1e0010">=</span> <span style="color:#66d9ef">$r6</span> <span style="color:#66d9ef">x</span> <span style="color:#66d9ef">$r1</span>    <span style="color:#960050;background-color:#1e0010">=&gt;</span> <span style="color:#66d9ef">$p8</span>  <span style="color:#960050;background-color:#1e0010">=</span> <span style="color:#66d9ef">$p20</span> <span style="color:#66d9ef">x</span> <span style="color:#66d9ef">$p25</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">$r8</span> <span style="color:#960050;background-color:#1e0010">=</span> <span style="color:#66d9ef">Load</span> <span style="color:#ae81ff">9</span>[<span style="color:#66d9ef">$r9</span>]  <span style="color:#960050;background-color:#1e0010">=&gt;</span> <span style="color:#66d9ef">$p5</span>  <span style="color:#960050;background-color:#1e0010">=</span> <span style="color:#66d9ef">Load</span> <span style="color:#ae81ff">9</span>[<span style="color:#66d9ef">$p22</span>]
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>對於 <code>$r5 = $r6 x $r1</code> 這條指令而言，<code>$r1</code> 的 physical register 應該來自於 <code>$r1 = $r1 + $r2</code> 中的 <code>$r1</code> destination register 所對應的 physical register，也就是：<code>$p31</code>，而非 RAT 所輸出的 <code>$p25</code>
<ul>
<li>如果不加以處理，運算結果就會有誤</li>
</ul>
</li>
</ul>
</li>
<li>
<p>需要有一個檢查機制，對 1 個 cycle 內的所有做 register renaming 的指令進行 <code>RAW</code> 的檢查</p>
<ul>
<li>
<p>在 register renaming stage，指令之間還是 in-order 的，因此只需要將所有指令的 source registers 與它前面所有指令的 destination registers 做比較，如果 registers 相同，那麼這個 source register 的 physical register 來源就不是 RAT，而是來自 free list</p>
<ul>
<li>如果多個 registers 皆相同，則使用最新指令的 physical register</li>
</ul>
</li>
<li>
<p>硬體設計如下圖：</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image%2017.png"></p>
<ul>
<li>第一條指令的 source registers 所映射的 physical registers 一定只能來自於 RAT，也不需要進行 RAW 的檢查</li>
<li>第二條指令的 source registers 所映射的 physical registers 有可能來自於 RAT，或是第一條指令的 destination physical register</li>
<li>第三、第四條指令也是類似的</li>
<li>此外，最後一條指令的 destination physical register 一定不會作為前面指令的 source register</li>
</ul>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image%2018.png"></p>
</li>
</ul>
</li>
</ul>
<h2 id="742---解決-waw-相關性">7.4.2 - 解決 WAW 相關性</h2>
<ul>
<li><code>WAW</code> 影響 RAT 和 ROB 的寫入過程，因此也需要在 register renaming stage 對其進行檢查：
<ol>
<li>
<p>對寫 RAT 進行檢查：</p>
<ul>
<li>如果 1 個 cycle 內有多條指令的 destination registers 都相同，那麼只有<strong>最新的那條指令的映射關係會被寫入 RAT</strong></li>
<li>每條指令都必須比較其 destination register 與所有在其後面的指令的 destination registers，如果發現有相同的 destination registers，則代表該條指令的 destination register 映射關係就不該被寫進 RAT
<ul>
<li>例如：
<ul>
<li>
<p>4 條在同一個 cycle 進行 register renaming 的指令，destination registers 分別為 <code>dst0</code>, <code>dst1</code>, <code>dst2</code>, <code>dst3</code>：</p>
<ul>
<li><code>dst0</code> 需要與 <code>dst1</code>、<code>dst2</code>、<code>dst3</code> 比較</li>
<li><code>dst1</code> 需要與 <code>dst2</code>、<code>dst3</code> 比較</li>
<li><code>dst2</code> 需要與 <code>dst3</code> 比較</li>
<li><code>dst3</code> 由於是最後一條指令，因此此 <code>dst3</code> 的映射關係一定會被寫進 RAT</li>
</ul>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image%2019.png"></p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p>對寫 ROB 進行檢查：</p>
<ul>
<li>
<p>為了能夠釋放那些不再使用的 physical register，同時又可以恢復處理器的狀態，每條指令的 destination register 都必須在做 register renaming 時，將舊的映射關係寫進 ROB 當中 (參考：<a href="#previous-physical-register-mapping-in-rob">link</a>)；如果在 1 個 cycle 內，有兩條以上的指令存在 <code>WAW</code>，那麼比較新的指令的 destination register 舊的映射關係就直接來自比較舊的那條指令，而不是來自於 RAT</p>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image%2020.png"></p>
<ul>
<li>指令 D 的 <code>$r0</code> 之前的 physical register 應該來自於指令 B 的 <code>$p31</code>，而不是 RAT 讀出的值</li>
</ul>
</li>
<li>
<p>每條指令都必須比較其 destination register 與所有在其前面的指令的 destination registers，如果發現有相同的 destination registers，則該條指令的 destination register 舊的映射關係就是與其最相近指令的 destination register 所對應的 physical register</p>
</li>
</ul>
<p><img alt="image.png" loading="lazy" src="/posts/superscalar-overview-ch7/image%2021.png"></p>
<ul>
<li>第一條指令由於前面沒有其他的指令，其 destination register 舊的映射關係只能是來自於 RAT</li>
<li>第二條指令必須和第一條指令的 destination register 比較</li>
<li>第三條指令必須和第二條、第一條指令的 destination registers 比較</li>
<li>第四條指令必須和第三、第二、第一條指令的 destination registers 比較</li>
</ul>
</li>
</ol>
</li>
</ul>
<h1 id="75---暫存器重命名過程的恢復">7.5 - 暫存器重命名過程的恢復</h1>
<ul>
<li>當發生 mis-prediction 或 exception 時，需要把在錯誤路徑上的指令給 flushed 掉；如果這些要被 flushed 的指令已經經過了 register renaming stage，就代表這些指令也佔據了 RAT、ROB、Issue Queue 等資源；當指令被 flushed 時，也需要將這些被佔據的資源給恢復，這樣才能保證後續的指令可以在一個正確的 pipeline 中開始執行</li>
<li>Register renaming 的恢復包含了：
<ul>
<li>ROB 的恢復</li>
<li>Issue Queue 的恢復</li>
<li>RAT 的恢復
<ul>
<li>以下方法對前面介紹的三種 register renaming 的方式 (使用 ROB 來實做暫存器重命名、擴充 ARF 來實做暫存器重命名、使用統一的 PRF 來實做暫存器重命名) 都適用：
<ul>
<li>使用 Checkpoint 來恢復 RAT</li>
<li>使用 WALK 來恢復 RAT</li>
<li>使用 Architecture State 來恢復 RAT</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="751---使用-checkpoint">7.5.1 - 使用 Checkpoint</h2>
<ul>
<li>對於一個實現了 Checkpoint 的 RAT 來說，在 SRAM 的每個最小儲存單元：MBC (Main Bit Cell) 周圍都加入同樣的儲存單元：CBC (Checkpoint Bit Cell)，這些 CBC 就實現了 Checkpoint 的功能，可以快速的完成 RAT checkpoint &amp; restore
<ul>
<li>當要保存 RAT 狀態時，就將 MBC 的內容複製到 CBC</li>
<li>當要恢復 RAT 狀態時，就將 CMC 的內容複製到 MBC</li>
</ul>
</li>
<li>cRAT 只需要保存 valid bits</li>
<li>sRAT 則需要將整個 SRAM 都保存下來，checkpoint 所需的電路面積很大，對處理器的速度和面積都會造成不小的負面影響，在設計時需要有所權衡</li>
</ul>
<h2 id="752---使用-walk">7.5.2 - 使用 WALK</h2>
<ul>
<li>Checkpoint 電路會增加硬體的開銷，因此，還有一種比較廉價的方式來保存和恢復 RAT 狀態，那就是使用 <strong>ROB</strong>
<ul>
<li>在 ROB 中保存每條指令之前 architecture registers → physical registers 的映射關係，利用這個資訊，就可以將 RAT 的狀態逐步地”倒回去”，使那些在錯誤路徑上的指令，一個一個恢復其對 RAT 的修改</li>
<li>這種方式稱為 WALK</li>
</ul>
</li>
<li>WALK 對 RAT 的恢復是比較慢的，它首先需要 flush 錯誤路徑上的指令，同時還需要逐個指令恢復 RAT，消耗非常多的時間
<ul>
<li>對於分支指令而言，這樣的方法會增加分支預測失敗時的 mis-penalty</li>
</ul>
</li>
<li>WALK 的優點就是消耗的硬體資源比較少，因此在某些 CPU 中，例如 MIPS R10000，就使用這種方法來恢復發生 exception 時的狀態
<ul>
<li>Exception 發生的頻率比分支預測失敗的頻率來得低，因此這種相對比較慢的方式在某些情況下也是可以接受的</li>
</ul>
</li>
</ul>
<h2 id="753---使用-architecture-state">7.5.3 - 使用 Architecture State</h2>
<ul>
<li>當需要從 CPU 外部存取一個 architecture register 時 (e.g. debugger)，直接使用 register renaming stage 的 RAT 是很難做到的，因為它仍處在 speculative 的階段，因此一般都會在 pipeline 的 commit stage 也使用一個 RAT，所有正確 retire 的指令都會將其對應的 physical registers 更新到這個 RAT，因此這個 RAT 所記錄的映射狀態肯定是正確的；這個 RAT 稱為 <strong>aRAT (Architecture RAT)</strong>
<ul>
<li>只有從 aRAT 才可以找到 architecture registers 對應的正確狀態的 physical registers</li>
</ul>
</li>
<li>利用 aRAT 也可以用來恢復 register renaming stage 的 RAT
<ul>
<li>舉例來說，當一條分支指令發生 mis-prediction 時，並不馬上進行 RAT 的恢復，而是讓 pipeline 繼續執行 (分支指令之前的 pipeline 必須 stall)，當這條分支指令變成 pipeline 中最舊的指令時，此時 aRAT 即表示了分支指令所對應的正確狀態的 RAT，因為分支指令之前的指令都已經順利 retired，並更新了 CPU 的狀態了
<ul>
<li>此時，便可以將 aRAT 內容，直接複製到 register renaming stage 的 RAT，就完成了 RAT 的恢復</li>
</ul>
</li>
</ul>
</li>
<li>但當在 execution stage 發現分支指令 mis-prediction 時，可能 pipeline 中還存有很多比這條分支指令還舊的指令；如果這些指令中包含了 D-cache miss 的 load 指令，那麼這條分支指令就可能得等待一段時間才能變為最舊的指令，這會增大 mis-penalty，一定程度上影響了處理器的效能</li>
<li>使用 aRAT 的好處：
<ul>
<li>在 superscalar CPU 中，在分支指令之前的指令，如果有指令發生了 exception，那麼就必須等到這條指令變為 pipeline 中最舊的指令時，將 pipeline 中的指令給全部 flush 掉，其中也包含了分支指令；由於這條分支指令並不會被執行，因此即使在 register renaming stage 做了 checkpoint 也是浪費，使用 aRAT 在這種情況下就不會白作工</li>
</ul>
</li>
</ul>
<h1 id="76---分發">7.6 - 分發</h1>
<ul>
<li>Pipeline 中的 <strong>Dispatch stage</strong> 就是 in-order execution 和 out-of-order execution 的分界點；指令經過 register renaming stage 後，就會進到 dispatch stage
<ul>
<li>在這個階段，經過 register renaming 後的指令會被寫到不同的 buffers 中，為 out-of-order execution 做好準備</li>
</ul>
</li>
<li>Buffers 主要分為三大類：
<ul>
<li>Issue Queue (out-of-order)
<ul>
<li>大部分的 FU (Function Unit) 都可以 out-of-order 來執行指令</li>
<li>當指令進到 Issue Queue 中時，其 operands 有可能還沒完全準備好，那麼就必須先在 Issue Queue 中等待</li>
<li>只要有任一條指令的 operands 都準備好了，就可以將其送到 FU 來執行，不用理會這條指令在程式中原先的執行順序 (i.e. out-of-order)</li>
<li>由於 out-of-order execution 的關係，Issue Queue 中的 empty entries 分佈是沒有規律的，需要有特別的設計方法</li>
</ul>
</li>
<li>Issue Queue (in-order)
<ul>
<li>即使在 out-of-order core 中，也是有部份的指令是照著程式中的執行順序來執行的，例如分支指令和 store 指令
<ul>
<li>這些指令如果按照 out-of-order 的方式來執行，會帶來不少的硬體消耗，且在性能上也不一定能提昇多少，因此對這些指令一般採取 in-order 的方式來執行</li>
</ul>
</li>
<li>Issue Queue 本質上就是一個 FIFO，透過調整 write pointer 就可以找到 free entries，將 register renaming 過的指令放到其中
<ul>
<li>可以透過 interleaving 的方式來實現這種 Issue Queue</li>
</ul>
</li>
</ul>
</li>
<li>ROB
<ul>
<li>ROB 可以將 out-of-order execution 的指令拉回程式的執行順序；指令經過 register renaming 後會按照程式的執行順序寫到 ROB 中
<ul>
<li>即使有些指令很早就完成執行了，它仍必須等到 ROB 中在它前面的指令執行完成後，才能被 retired 並更新 CPU 的 architecture state (程式可見)</li>
</ul>
</li>
<li>ROB 本質上也是一個 FIFO，透過調整 write pointer 就可以找到 free entries，將 register renaming 過的指令放到其中</li>
</ul>
</li>
</ul>
</li>
<li>Pipeline 中的 <strong>dispatch stage</strong> 就是將 register renaming 後的指令寫到 Issue Queue 和 ROB 的過程，指令被 dispatched 到 Issue Queue 後，就可以以 out-of-order 的方式來執行了，而透過 ROB 可以將 out-of-order execution 的指令拉回程式的執行順序</li>
<li>Dispatch 可以跟 register renaming 放在同一個 cycle 內完成，但當 Issue Queue 和 ROB 的容量比較大時，向它們寫入資料會變得很慢，嚴重影響 CPU 的 cycle time，因此很多 CPU 都會將 dispatch 獨立為一個 stage</li>
</ul>
]]></content:encoded>
    </item>
  </channel>
</rss>
