愛伊米

數字系統重要指標-吞吐率和時延

數字系統重要指標-吞吐率

吞吐率被定義為數位電路單位時間內傳輸資料的量或單位時間完成的工作量。傳輸的資料越多或做的工作越多,則吞吐率越高。吞吐率有時候和效能、頻寬可以互換使用。對於CPU來說,吞吐率定義為單位時間內能夠執行的指令數。對於DDR儲存器來說,吞吐率定義為從儲存器中寫入或讀取的資料量。

經常和吞吐率一起出現的術語是延遲,我們會發現,延遲和吞吐率是兩個不同的概念(後面會介紹延遲)。當談論吞吐率的時候,我們一般談論的是支援多大的吞吐率。為了獲得吞吐率,我們需要測量—段時間內傳輸的資料量或執行的指令數。這是一個平均數值而不是瞬時數值。

延遲是指從加入激勵到得到第一個輸出結果需要的最短時間。例如,你種植一棵檸檬樹,等待它結出果實,它可能過了一年才結出第一批果實。你對降低延遲(一年)無能為力。但是,你可以透過種植10棵樹來增加檸檬的產量,你會得到10倍的果實,但是你還是要等一年才能得到第一批水果對於多數設計來說,有一些方法可以降低延遲,但大多數情況下是無能為力的。下面我們將討論降低延遲的方法。

在一些應用中,吞吐率至關重要,而在一些情況下,降低延遲是設計的重點。例如,當對DRAM寫人大量的資料時,具有高吞吐率就很重要。而另一方面,對類似於線上翻譯伺服器這類裝置來說,使用者需要快速獲得返回結果,降低延遲就變得更為重要。

增加吞吐率的方法

當我們設計一個系統或一個晶片的架構時,希望盡力獲得高吞吐率。提高吞吐率涉及多個關鍵技術點,假如我們能夠理解這些關鍵技術點是如何工作的,以及它們之間存在怎樣的關聯,那麼我們就能把這些關鍵技術點以最好的方式組合起來以實現期望的目標。下面將對影響吞吐率的關鍵技術點進行逐一分析。

更高的頻率

當今的數字系統以同步系統為主,都需要一個或多個時鐘。一個增加資料傳輸速率或指令執行速度的常用方法是使用更高頻率的時鐘,在時鐘頻率增加的情況下,系統的處理能力就會得到不斷提升,處理器設計中通常採用這種方法。然而,這種方式會有負面效應,原因記功率消耗和時鐘頻率成正比例關係。假如設計的是低功耗電路,透過增加頻率來滿足吞吐率的要求並不是很好的方法,此時可能需要考慮其他的技術手段。當前流行的處理器設計趨勢並不是僅僅把處理器時鐘頻率的提高作為目標。例如,透過設計多核系統和採用多通道儲存器可以在不提高主頻的情況下提高處理能力。

更寬的資料通道

設計者可以透過增加資料匯流排的位寬來提高資料吞吐率。在時鐘頻率不變的情況下,增加資料匯流排的位寬可以增加資料吞吐率,就像四車道的公路比兩車道的公路單位時間內可以透過更多的車輛一樣。例如,PCIe匯流排可以連線1個通道、2個通道直至32個通道。假設需要設計一個SA SPCIe控制卡,或一個PCIe SSD卡,那麼需要用多少個通道的PCIe匯流排呢?首先,需要計算HDD或SSD讀寫需要的頻寬,然後選擇一個xl,x2x4或甚至x8的PCIe聯結器。所選擇的PCIe匯流排聯結器的頻寬需要與儲存器的訪問頻寬相同或比後者大。另外設計時要考慮到PCIe協議的開銷,和任何協議一樣,PCIe上並不是所有的時鐘週期都可以用來傳輸使用者資料。

在實際設計中,通常需要對匯流排的工作時鐘頻率和匯流排的位寬進行折中考慮。在給定系統所需傳輸頻寬的情況下,需要選擇合適的資料線的寬度和工作頻率。例如,64位、800MHz,128位、400MHz和256位、200MHz的匯流排具有相同的頻寬,應如何選擇呢?增大匯流排寬度會使接外掛變得更大,晶片引腳更多,從而增加裝置的硬體成本;提高匯流排頻率會增加系統設計難度,需要更多地考慮高頻訊號中常出現的電磁相容和訊號傳輸質量問題。

我們可以假定一個這樣的場景:我們選擇64位資料通道進行背靠背的資料包傳輸,在一個時鐘週期裡可以並行傳送4位元組,它們分屬於不同的資料包。在這種情況下,使用一個低速時鐘進行資料處理是非常煩瑣的。此外,低速時鐘意味著更大的延遲(進行資料處理需要的時間更長)。如果一個設計佔用的邏輯閘資源不多,對延遲也不敏感,那麼使用較為早期的低端工藝進行晶片設計就可以滿足需求。如果希望降低延遲,同時預算充足,可以採用最為先進的工藝,使用更高的時鐘頻率和更窄的資料通道。

流水線

所有當前先進的處理器都採用流水線結構來增加吞吐率。假如一條指令需要n個步驟才能完成執行,那麼它需要n級流水線。當第一條指令開始執行第二個步驟時,一條新的指令可以開始執行第一個步驟,後續的指令依次不斷進人流水線。當第一條指令完成n個步驟之後,每個時鐘週期都會有一條指令執行完成。假如不使用流水線,那麼需要等一條指令執行完之後才開始另一條指令,效率就只有原來的1/n。流水線的概念不僅適用於處理器,在許多系統中都有應用。一個PCIe IO擴充套件卡可以向主儲存器發起讀操作命令,該指令的操作需要一定的時間和操作步驟,擴充套件卡可以在前一條指令尚未完成時就發出後續的指令,以此來提高匯流排的吞吐率。設計者還可以利用此概念設計高速流水線結構的加法器和乘法器。當我們設計一個協議時,可以考慮採用流水線來增加吞吐率。

並行處理

並行處理與流水線不同,在並行處理中,會同時用到更多的資源。現代處理器中常常會同時存在多個執行緒,其中每一個執行緒以流水線方式工作。每條執行緒在一個時鐘週期內執行一條指令或每秒鐘執行m條指令。當有n條執行緒時,一秒內可以執行m x n條指令。

並行處理過程可以用超級市場出口處的收銀-打包臺來類比。每個出口處需要兩名工作人員,一個收銀,一個進行商品裝袋打包,兩個人構成一條簡單的流水線,多個收銀-打包出口構成多個並行的執行緒。商場可以根據客流量調整出口的數量。

無序執行(亂序執行)

一個晴朗的週六早晨,我的妻子給我佈置了六件無序的工作(列在一張紙上)。只要在一定時間內把六件事都完成她就會很開心。她並不關心我先做哪件事後做哪件事,除非它們前後有依賴關係。我看了看清單,記下了需要去的幾個地方,列出了一個處理順序,然後完成它們。我重新將它們排序可以基於總路程最短,或根據我的喜好,把喜歡做的事放在最前面,討厭的放在後面。此時處理順序可能不是最有效率的,但我可能更喜歡這樣做。

不需要按照嚴格的順序執行n項任務為在儘可能短的時間內完成全部任務提供了最佳化的可能,這也就增加了電路的吞吐率。SATA和SAS協議支援的NCQ(Native Command Queuing)就是這樣一種最佳化技術。作業系統向磁碟傳送一組讀寫操作命令,資料儲存在磁碟中,根讀/寫磁頭和資料的相對位置,單個命令花費的時間是不同的,磁碟驅動電路分析所有的操作命令,根據一些演算法(如最少搜尋演算法)確定內部的執行順序,從而提高整體讀寫效率。

當前的處理器將指令分解成若干微程式碼,傳送到指令池中。然後,微程式碼以無序的方式執行然而從外部看,這些指令完成的順序和指令取出的順序是相同的。例如,指令1和指令2兩條指令先後進入指令池進行亂序執行,如果指令2的所有微程式碼都已執行完畢,但是指令1中仍然有一條微程式碼尚未完成。在這種情況下,指令2必須等待指令1完成後才能完成並返冋執行結果。從整體上看,雖然存在內部等待,但以無序方式執行微程式碼可以提高整體效率,因此具有更高的吞吐率。

另外一個是儲存器控制器的例子。一個PCIe卡能夠向主儲存器傳送多個儲存器讀操作命令。儲存器控制器可以重新對儲存器讀操作命令進行排序(基於被讀取資料所在的儲存區域)。儲存器控制器返回的讀出資料的輸出順序和PCIe卡發岀的讀操作命令的順序可能不同,PCIe會確保系統的正常工作。如果PCIe卡在某些情況下需要保證讀出順序,那麼它必須等待該資料被讀出後才發出後續的操作命令。從整體上說,儲存器控制器的這種亂序工作方式可以提高儲存訪問的吞吐率。

快取記憶體(cache)

處理器經常利用cache來提高系統性能。系統啟動之後,作業系統和使用者程式從硬碟載入到記憶體(RAM)中。所有的命令都保留在RAM中,當處理器要執行某個指令時,它會從記憶體中讀取該指令。類似地,處理器也會對RAM進行資料讀寫。理論上,這就是計算機的執行方式,但是存在一個問題,那就是RAM的讀寫時間比較長,需要多個時鐘週期(或者說指令週期)才能完成。

為了改進效能,處理器使用一個容量較小的儲存器,將部分指令和資料存入其中,這個更小的儲存器稱為cache(快取記憶體)。快取記憶體離CPU更近,執行速度更快,幾乎和CPU核心的速度是一樣的。當處理器需要讀入指令和資料時,它會首先讀取快取而不是儲存器。只有當需要的指令和資料不在快取中時,才會去記憶體中讀取。這種方式可以減少記憶體訪問的次數,提高系統性能。目前的高效能處理器中通常採用兩級cache(L1 cache和L2 cache)。

快取記憶體的概念可以進行推廣,當一個系統的兩個部分在執行速度方面差別較大時,可以在快速裝置和慢速裝置之間插入cache,一些硬體裝置,如硬碟等,讀寫速度相對較慢,此時硬碟驅動電路中可以使用一個本地快取來儲存從磁碟讀取的資料,當讀操作指令到達硬碟驅動電路時,它能很快地從本地快取中返回資料,而不是花費更長的時間讀取磁碟中的資料。cache也用來提高寫入的效能,當CPU向主儲存區寫資料時,它會花費很長的時間。這時CPU處於空置狀態不能執行其他指令。此時可以設定一個寫快取,CPU將需要寫入的資料寫入cache中即可,此後CPU繼續執行其他指令,驅動電路負責將cache中的資料以較低的速度寫入儲存器中。

固態盤(Solid-State Drive),如Flash儲存器的驅動電路中也使用本地快取提高寫和讀的效能。固態盤的一個特點是讀/擦除的次數是受限的。固態盤的寫快取在資料寫入時先將資料快取下來,向CPU發出ACK確認資訊,然後再將資料寫入儲存器。採用寫快取還有一個優點,假如存在對同一個地址的多次寫操作,那麼固態盤驅動電路只將最後一個數據真正寫入儲存器中,這就減少了快閃記憶體寫入的次數,提高了固態盤的使用壽命。

cache並不只在硬體設i十中使用,在軟體設計中也經常用到。搜尋引擎在網路中查詢並在本地儲存所需要的資訊,當用戶進行網路搜尋時。可以直接在搜尋引擎所儲存的資料中進行查詢,而不是到Internet中進行搜尋,這樣就可以提高搜尋速度。

預讀取

資料預讀取的含義是在快取區中預先存入比當前需求更多的資料由於實際應用屮許多資料是連續儲存和使用的,提前讀入一些資料到快取區中可以減少對儲存介質的訪問,從而提高讀取速度。

多核

現代的處理器經常採用多核(例如,8核或16核)結構。每個核都是一個完整的CPU多個CPU能並行地進行資料處理。’

在一個高效能儲存器控制器中,可能存在多個DDR控制器,它們獨立地連線不同的DDR儲存器。同樣,高效能的SSD控制器同時存在多個Flash控制器,它們也能獨立地同時進行Flash讀寫。

時延

時延,如前所述,是從操作或命令開始執行到獲得資料或結果的最短時間。時延和吞吐量是兩個常用概念,是一個系統的兩個不同方面。通常兩者相互獨立,但也存在著一些相互關聯和影響。在同步通訊中,時延決定著一個獨立工作流的吞吐量。

以CPU訪問儲存器為例,假如CPU希望從主儲存器中讀取資料,那麼它會發出儲存器讀指令以讀取64位元組資料(64字行通常被稱為一個cache line)。假如讀取資料的前8位元組耗時0。5us,那麼時延就為0。5us。我們再舉一個PCIe網絡卡從主儲存器中以DMA方式讀取資料的例子,該讀操作大概需要2us時間,此時時延即為2us。如果PCIe網絡卡支援背靠背的儲存器讀操作,那麼就能夠增加吞吐量。此時,獲得讀取的第一個資料包需要2us,但是後來的資料包會連續到達。如果我們在一個相對較長的時間內連續進行資料讀寫,那麼時延就不會對吞吐量產生明顯的影響。

在一些情況下,時延會影響到吞吐量。在使用一些具有互控機制的通訊協議時(如處理器之間的通訊),一些指令只有在收到完整的資料之後才能執行,此時吞吐率就會直接受到時延的影響。在這種情況下,我們需要儘量減小時延。另外,對於線上業務或計算機處理的股票交易中,時延也是非常重要的。假如根據使用者的查詢要求,裝置需從儲存器中讀取4K位元組節的資料,那麼系統設計者需要考慮儘可能快地返冋需要的資料,使得時延越小越好。

降低時延的方法

有沒有降低時延的有效方法呢?毫無疑問是有的。在很多應用中需要使用FIFO(First In First Out,先入先出儲存器),FIFO會引入時延。在FIFO中,先到達的資料會先被讀出,如果寫入端的速度高於讀出端,FIFO的可用儲存空間就會減小到零。如果一個對時延敏感的包到了一個FIFO佇列中,由於其排列在FIFO佇列中的後面,因此必須等前面的資料被讀出後才能讀出該資料,這就會帶來時延。在進行晶片架構設計時,會常常用到非同步FIFO進行跨時鐘域資料傳遞,而有時採用簡單的握手機制就可以進行跨時鐘域的資料傳遞,這有利於減少延遲。

晶片的時鐘頻率也會直接影響時延,對於同一個電路來說,時鐘頻率高時,可以更迅速地進行資料處理和操作。以PCIe交換電路為例,其目標是使輸入的資料包快速地被交換到輸出端。此時,使用高頻內部時鐘可以提高資料包轉發速度並能夠降低時延。

在乙太網交換電路或PCIe交換電路中,可以使用直接透明分組轉發模式替代儲存轉發模式來降低時延。目前,在大多數應用中,資料以包的形式進行轉發。在乙太網交換電路中,當數倨包到達輸入端後,先儲存在緩衝區中。由於乙太網幀中的CRC校驗域在幀的末尾,在接收資料的過程中,本地CRC校驗電路一邊接收資料,一邊進行CRC校驗計算,當完整的幀接收完畢後,將本地的CRC計算結果和接收的校驗結果進行比較,如果二者相同,則接收此幀;如果不同,則丟棄此幀。

根據CRC校驗的工作機制,只有一個幀被完整地接收後才可以判斷該幀是否存在錯誤,因此接收延遲與幀長有直接關係。採取儲存轉發機制時,對整個交換機而言,資料幀從輸入到輸出的時延與幀長冇關,對於整個系統而言,端到端的延遲還與資料幀所經過的交換機數量有關。

採用直接透明分組轉發模式時,交換電路可以在包到達輸入端的時候就開始進行轉發,這樣可以大大降低時延。採用這種方式時,如果發生了CRC校驗錯誤應該怎樣處理呢?此時,可以將CRC檢錯功能放到終端中進行,當鏈路誤位元速率非常低時,這種工作方式可以有效地降低延遲。

降低時延還有許多其他的方法,下面介紹其中的一種。例如,CPU需要讀取儲存器中從地址8到地址15的8位元組資料。考慮到讀取的效率,儲存器控制器從儲存器中連續取64位元組(1個cache line),而不是8位元組。此時,儲存器控制器從地址0到地址63連續讀出了64位元組的資料。此後,儲存器控制器可以將地址0到地址63的64位元組交給CPU如果CPU希望快速讀取位元組8~15,儲存器控制器可以從地址8開始讀取資料,當地址到達63後,再讀出地址0到地址7所儲存的資料。

NOW

學習Xilinx FPGA最好的資料其實就是官方手冊,下表總結了部分手冊的主要介紹內容,關注我,持續更新中……