PCIe協議是一種端對端的互連協議,提供了高速傳輸頻寬的解決方案。目前PCIe已經發展到第四代PCIe4.0, 每一代的發展,最明顯的特徵就是速率翻倍,如下表,從最初的2.5GT/s,到現在的PCIe 4.0的16GT/s.
在上圖中有一個欄位,名稱叫做Raw Bit Rate,翻譯過來就是原始位元率。那麼,這個原始位元率(RBR)與真實的資料傳輸速度之間是什麼關係呢?有什麼區別?這就是我們本篇文章想要思索的問題。
在PCIe匯流排中,事務傳輸型別有四種,Memory,IO,Configuration,Message,如下圖。
不過,PCIe系統針對傳輸速率的最佳化都主要集中提高Memory型別事務的傳輸速率,所以,我們在這裡提到的傳輸速率,主要是Memory data的傳輸速率。另外,鑑於PCIe 4.0相關產品問世還有一段時間,我們在這裡也先跳過PCIe 4.0。
PCIe Spec定義Gen1的最大傳輸速率是2.5Gb/s, Gen2的最大傳輸速率是5.0Gb/s, Gen3的最大傳輸速率是8.0Gb/s. 在這裡的最大傳輸速率指的是單lane單向的原始位元傳輸速率(Raw bit rate), 並不是PCIe系統中真正的資料傳輸速率。因為在PCIe系統存在一定的資料傳輸開銷和設計取捨。
任何資料在PCIe系統傳輸,都會產生一定的開銷。我們從以下五個方面探究一下:
(1) 資料編碼: Gen1/2 8b/10b & Gen3 128b/130b
Gen1/Gen2採用8b/10b編碼,直觀的理解,就是把8bit資料轉換為10bit資料傳輸,目的就是維持"直流平衡(DC Balance)",讓1和0傳輸數目相等。因為高速序列傳輸過程中,如果有連續多位1或者0沒有變化,那麼,訊號傳輸就會由於電壓位階的關係而發生錯誤。
Gen1/Gen2採用8b/10b編碼進行資料傳輸,就相當於多了20%傳輸開銷。同理,Gen3採用了128b/130b編碼傳輸,就等於多了2%的開銷。
(2) TLP資料包開銷
PCIe屬於封裝分層協議,資料報文在Device Core產生之後,在分別經過事務層(Transaction Layer)、資料鏈路層(Data Link Layer)、物理層(Physical Layer)之後會依次被增加ECRC,Sequence Number,LCRC,Start,END等資料塊。,
TLP header有兩種選擇12 bytes或者16bytes,主要與Memory Read/Write TLP中採用32位地址或者64位地址有關。
如果採用32位地址,那麼TLP Header的長度是12bytes:
如果採用64位地址,那麼TLP Header的長度是16bytes:
所以,在TLP傳輸過程中,就增加了20~30 Bytes的開銷。
(3) 流量開銷(Traffic Overhead)
在資料鏈路層(Data link layer)和物理層(Physical Layer)都會引入流量開銷(Traffic Overhead).
資料鏈路層在PCIe匯流排中的作用就是保證來自事務層TLPs的正確傳輸。為了實現這一目的,資料鏈路層又定義了DLLP(Data Link Layer Packets)。DLLP產生於資料鏈路層,終止於資料鏈路層。定義的DLLP資料型別主要有Ack, Nak, PM,FC等,如下圖。
在PCIe Link達到正常的工作狀態(L0)之後,如果兩個互動port口之間存在延時,那麼這個時候就需要物理層插入SKP Order sets來補償PCIe鏈路中的延時。對於Gen1/Gen2, SKP OS的大小為4 Bytes;對於Gen3, SKP OS的大小一般為16 Bytes. PCIe Spec規定,在TLP傳輸過程中,不允許插入Order Sets,SKP OS只能在TLP傳輸間隙進行。
所以,Ack/Nak/PM/FC等DLLP和Order Sets都會影響到資料傳輸的速率。
(4) 協議開銷
PCIe Spec規定,傳送端傳送TLP之後,需要接受端迴應Ack或者Nak, 以得知傳送的TLP是否被成功接收。傳送端需要將TLP儲存在TLP retry buffer中,直到收到Ack成功接收的迴應。如果不幸的收到了Nak未成功接收的迴應,那也不怕,只要將放在TLP retry buffer中的TLP再次傳送,直到被正確接收。
如果傳送每個TLP之後,都要求對應一個Ack迴應,那麼,當傳送多個TLP時,就需要對應多個Ack迴應,這樣的話,會嚴重的增加PCIe鏈路中的資料傳輸開銷。為了減少這方便的開銷,PCIe允許傳送多個TLP後,有一個Ack迴應就可以。如下圖,傳送5個TLP,收到一個Ack迴應。
這樣做的好處可以降低開銷,但是不能消除開銷。
(5) 流量控制(Flow Control)機制的開銷
在PCIe鏈路中,我們不能一直髮送TLP,而是需要接受端有足夠的接受空間之後,才能繼續傳送TLP,這個過程就是PCIe協議中的流量控制(Flow Control)機制。
接收端會透過不斷地傳送FC DLLP來告知傳送端,此時接收端可用Buffer的大小。如果接收端的Buffer快滿時,傳送端就會停止傳送TLP,這樣做的目的就是防止Buffer空間不足而造成TLP被丟棄。
所以,接收端可用Buffer的大小很大程度上影響著資料傳輸速率。
除了上面提到的協議和流量開銷外,對傳輸速率也有一定影響的因素就是系統引數,比如MPS(Maximum Payload Size), MRRS(Maximum Read Request Szie), Request Type等。
(1) MPS(Maximum Payload Size)
PCIe協議對MPS支援的大小有6種: 128B,256B,512B,1024B,2048B,4096B.
PCIe系統中的最大負載MPS是在上電列舉和配置階段定義的,以PCIe系統中最小MPS為準。比如,下圖,RC,Switch,Endpoint都有不同的MPS設定,那麼,就取最小MPS 128 Bytes為準。這個過程,類似水桶原理。
MPS的大小影響著資料傳輸的效率。資料傳輸效率計算公式:
我們假設TLP中的Header大小為12 Bytes, 同時沒有ECRC,這樣的話,TLP傳輸就有20bytes的額外開銷。那麼,不同MPS大小對應的傳輸效率計算結果如下:
從計算結果來看,隨著MPS的增加,傳輸效率在增加,但是增幅在變小,作個曲線表示如下:
(2) MRRS(Maximum Read Request Size)
PCIe協議中,MRRS代表著讀請求最大Size,對於MRRS選擇,同樣有6種:128B,256B,512B,1024B,2048B,4096B. 這個引數也是在Configuration階段,寫入到裝置的control暫存器。
由於不攜帶任何資料,所以每次的讀請求都是一筆額外的開銷。如果我們設定MRRS為128B,我們讀64KB資料時,就需要傳送512(64KB/128B=512)次讀請求,這樣的話,就增加了很多額外的開銷,對資料傳輸速率也是一種傷害。
假設Write TLP的數量是200, MPS=128B,PCIe系統是Gen1 x8.
(1) 計算Symbol Time
我們知道是Gen1,傳輸速率是2.5Gb/s. 那麼,
Symbol Time(傳輸1byte的時間)=1B/2.5Gb/s=4ns.
因為是8 lane,那麼,每4ns可以傳送8Byte資料。
(2) 計算TLP和DLLP傳輸時間
在MPS=128B,32bit地址的情況下,Memory Write TLP的傳輸時間就等於:
[(128B payload+ 20B overhead)/8B/Clock]*4ns/Clock=74 ns.
DLLP的傳輸時間就等於:
[8B / 8B/Clock] * [4ns/Clock] = 4 ns.
另外,我們在這裡假設,每傳輸5個TLPs, 對應一個Ack DLLP。每傳輸4個TLPs,有一個FC update DLLP.
(3) 計算傳輸頻寬
傳輸資料總量(Bytes)=200 posted writes × 128 bytes/posted write = 25,600 bytes.
傳輸時間=(200 × 74 ns) + (40 × 4 ns) + (50 × 4 ns) = 15,160 ns.
傳輸頻寬=[25,600 bytes / 15,160 ns] = 1.689 GB/s or 1,689 MB/s.
假設讀取資料量=4096B, MRRS=256B,PCIe系統是Gen1 x8.
在32bit地址的情況下,MemoryRead TLP的傳輸時間就等於:
[20B overhead/8B/Clock]*4ns/Clock=10 ns.
假設RCB(Read Completion Boundary)=64 Bytes,所以,多數的Completion TLP都是64B大小。
[(64 bytes payload + 20 bytes overhead) / 8 bytes/clock] × [4 ns/clock] = 42 ns.
另外,我們在這裡假設,每傳輸5個TLPs, 對應一個Ack DLLP。每傳輸4個TLPs,有一個FC update DLLP. 從傳送Read請求,到Completion產生的時間為300ns.
傳輸資料總量(Bytes)=4096 bytes.
傳輸時間=(16 × 10 ns) + (16 × 300 ns) + (64 × 42 ns) + (16 × 4 ns) + (20 × 4 ns) = 7,792 ns.
傳輸頻寬=[4096 bytes / 7,792 ns] × [1 GB / 1s] = 0.523 GB/s or 523 MB/s.
PCIe協議是一種端對端的互連協議,提供了高速傳輸頻寬的解決方案。目前PCIe已經發展到第四代PCIe4.0, 每一代的發展,最明顯的特徵就是速率翻倍,如下表,從最初的2.5GT/s,到現在的PCIe 4.0的16GT/s.
在上圖中有一個欄位,名稱叫做Raw Bit Rate,翻譯過來就是原始位元率。那麼,這個原始位元率(RBR)與真實的資料傳輸速度之間是什麼關係呢?有什麼區別?這就是我們本篇文章想要思索的問題。
資料傳輸速率定義在PCIe匯流排中,事務傳輸型別有四種,Memory,IO,Configuration,Message,如下圖。
不過,PCIe系統針對傳輸速率的最佳化都主要集中提高Memory型別事務的傳輸速率,所以,我們在這裡提到的傳輸速率,主要是Memory data的傳輸速率。另外,鑑於PCIe 4.0相關產品問世還有一段時間,我們在這裡也先跳過PCIe 4.0。
PCIe Spec定義Gen1的最大傳輸速率是2.5Gb/s, Gen2的最大傳輸速率是5.0Gb/s, Gen3的最大傳輸速率是8.0Gb/s. 在這裡的最大傳輸速率指的是單lane單向的原始位元傳輸速率(Raw bit rate), 並不是PCIe系統中真正的資料傳輸速率。因為在PCIe系統存在一定的資料傳輸開銷和設計取捨。
資料傳輸開銷任何資料在PCIe系統傳輸,都會產生一定的開銷。我們從以下五個方面探究一下:
(1) 資料編碼: Gen1/2 8b/10b & Gen3 128b/130b
Gen1/Gen2採用8b/10b編碼,直觀的理解,就是把8bit資料轉換為10bit資料傳輸,目的就是維持"直流平衡(DC Balance)",讓1和0傳輸數目相等。因為高速序列傳輸過程中,如果有連續多位1或者0沒有變化,那麼,訊號傳輸就會由於電壓位階的關係而發生錯誤。
Gen1/Gen2採用8b/10b編碼進行資料傳輸,就相當於多了20%傳輸開銷。同理,Gen3採用了128b/130b編碼傳輸,就等於多了2%的開銷。
(2) TLP資料包開銷
PCIe屬於封裝分層協議,資料報文在Device Core產生之後,在分別經過事務層(Transaction Layer)、資料鏈路層(Data Link Layer)、物理層(Physical Layer)之後會依次被增加ECRC,Sequence Number,LCRC,Start,END等資料塊。,
不過,需要注意的是,Gen1和Gen2有End識別符號,Gen3則沒有End識別符號。Gen2 TLP:Gen3 TLP:TLP header有兩種選擇12 bytes或者16bytes,主要與Memory Read/Write TLP中採用32位地址或者64位地址有關。
如果採用32位地址,那麼TLP Header的長度是12bytes:
如果採用64位地址,那麼TLP Header的長度是16bytes:
所以,在TLP傳輸過程中,就增加了20~30 Bytes的開銷。
(3) 流量開銷(Traffic Overhead)
在資料鏈路層(Data link layer)和物理層(Physical Layer)都會引入流量開銷(Traffic Overhead).
資料鏈路層在PCIe匯流排中的作用就是保證來自事務層TLPs的正確傳輸。為了實現這一目的,資料鏈路層又定義了DLLP(Data Link Layer Packets)。DLLP產生於資料鏈路層,終止於資料鏈路層。定義的DLLP資料型別主要有Ack, Nak, PM,FC等,如下圖。
在PCIe Link達到正常的工作狀態(L0)之後,如果兩個互動port口之間存在延時,那麼這個時候就需要物理層插入SKP Order sets來補償PCIe鏈路中的延時。對於Gen1/Gen2, SKP OS的大小為4 Bytes;對於Gen3, SKP OS的大小一般為16 Bytes. PCIe Spec規定,在TLP傳輸過程中,不允許插入Order Sets,SKP OS只能在TLP傳輸間隙進行。
所以,Ack/Nak/PM/FC等DLLP和Order Sets都會影響到資料傳輸的速率。
(4) 協議開銷
PCIe Spec規定,傳送端傳送TLP之後,需要接受端迴應Ack或者Nak, 以得知傳送的TLP是否被成功接收。傳送端需要將TLP儲存在TLP retry buffer中,直到收到Ack成功接收的迴應。如果不幸的收到了Nak未成功接收的迴應,那也不怕,只要將放在TLP retry buffer中的TLP再次傳送,直到被正確接收。
如果傳送每個TLP之後,都要求對應一個Ack迴應,那麼,當傳送多個TLP時,就需要對應多個Ack迴應,這樣的話,會嚴重的增加PCIe鏈路中的資料傳輸開銷。為了減少這方便的開銷,PCIe允許傳送多個TLP後,有一個Ack迴應就可以。如下圖,傳送5個TLP,收到一個Ack迴應。
這樣做的好處可以降低開銷,但是不能消除開銷。
(5) 流量控制(Flow Control)機制的開銷
在PCIe鏈路中,我們不能一直髮送TLP,而是需要接受端有足夠的接受空間之後,才能繼續傳送TLP,這個過程就是PCIe協議中的流量控制(Flow Control)機制。
接收端會透過不斷地傳送FC DLLP來告知傳送端,此時接收端可用Buffer的大小。如果接收端的Buffer快滿時,傳送端就會停止傳送TLP,這樣做的目的就是防止Buffer空間不足而造成TLP被丟棄。
所以,接收端可用Buffer的大小很大程度上影響著資料傳輸速率。
系統引數對傳輸速率的影響除了上面提到的協議和流量開銷外,對傳輸速率也有一定影響的因素就是系統引數,比如MPS(Maximum Payload Size), MRRS(Maximum Read Request Szie), Request Type等。
(1) MPS(Maximum Payload Size)
PCIe協議對MPS支援的大小有6種: 128B,256B,512B,1024B,2048B,4096B.
PCIe系統中的最大負載MPS是在上電列舉和配置階段定義的,以PCIe系統中最小MPS為準。比如,下圖,RC,Switch,Endpoint都有不同的MPS設定,那麼,就取最小MPS 128 Bytes為準。這個過程,類似水桶原理。
MPS的大小影響著資料傳輸的效率。資料傳輸效率計算公式:
我們假設TLP中的Header大小為12 Bytes, 同時沒有ECRC,這樣的話,TLP傳輸就有20bytes的額外開銷。那麼,不同MPS大小對應的傳輸效率計算結果如下:
從計算結果來看,隨著MPS的增加,傳輸效率在增加,但是增幅在變小,作個曲線表示如下:
(2) MRRS(Maximum Read Request Size)
PCIe協議中,MRRS代表著讀請求最大Size,對於MRRS選擇,同樣有6種:128B,256B,512B,1024B,2048B,4096B. 這個引數也是在Configuration階段,寫入到裝置的control暫存器。
由於不攜帶任何資料,所以每次的讀請求都是一筆額外的開銷。如果我們設定MRRS為128B,我們讀64KB資料時,就需要傳送512(64KB/128B=512)次讀請求,這樣的話,就增加了很多額外的開銷,對資料傳輸速率也是一種傷害。
寫入吞吐量(Write Throughput)計算方式假設Write TLP的數量是200, MPS=128B,PCIe系統是Gen1 x8.
(1) 計算Symbol Time
我們知道是Gen1,傳輸速率是2.5Gb/s. 那麼,
Symbol Time(傳輸1byte的時間)=1B/2.5Gb/s=4ns.
因為是8 lane,那麼,每4ns可以傳送8Byte資料。
(2) 計算TLP和DLLP傳輸時間
在MPS=128B,32bit地址的情況下,Memory Write TLP的傳輸時間就等於:
[(128B payload+ 20B overhead)/8B/Clock]*4ns/Clock=74 ns.
DLLP的傳輸時間就等於:
[8B / 8B/Clock] * [4ns/Clock] = 4 ns.
另外,我們在這裡假設,每傳輸5個TLPs, 對應一個Ack DLLP。每傳輸4個TLPs,有一個FC update DLLP.
(3) 計算傳輸頻寬
傳輸資料總量(Bytes)=200 posted writes × 128 bytes/posted write = 25,600 bytes.
傳輸時間=(200 × 74 ns) + (40 × 4 ns) + (50 × 4 ns) = 15,160 ns.
傳輸頻寬=[25,600 bytes / 15,160 ns] = 1.689 GB/s or 1,689 MB/s.
讀取吞吐量(Read Throughput)計算方式假設讀取資料量=4096B, MRRS=256B,PCIe系統是Gen1 x8.
(1) 計算Symbol Time
我們知道是Gen1,傳輸速率是2.5Gb/s. 那麼,
Symbol Time(傳輸1byte的時間)=1B/2.5Gb/s=4ns.
因為是8 lane,那麼,每4ns可以傳送8Byte資料。
(2) 計算TLP和DLLP傳輸時間
在32bit地址的情況下,MemoryRead TLP的傳輸時間就等於:
[20B overhead/8B/Clock]*4ns/Clock=10 ns.
DLLP的傳輸時間就等於:
[8B / 8B/Clock] * [4ns/Clock] = 4 ns.
假設RCB(Read Completion Boundary)=64 Bytes,所以,多數的Completion TLP都是64B大小。
[(64 bytes payload + 20 bytes overhead) / 8 bytes/clock] × [4 ns/clock] = 42 ns.
另外,我們在這裡假設,每傳輸5個TLPs, 對應一個Ack DLLP。每傳輸4個TLPs,有一個FC update DLLP. 從傳送Read請求,到Completion產生的時間為300ns.
(3) 計算傳輸頻寬
傳輸資料總量(Bytes)=4096 bytes.
傳輸時間=(16 × 10 ns) + (16 × 300 ns) + (64 × 42 ns) + (16 × 4 ns) + (20 × 4 ns) = 7,792 ns.
傳輸頻寬=[4096 bytes / 7,792 ns] × [1 GB / 1s] = 0.523 GB/s or 523 MB/s.