之前我们讲了对PCIe的一些基础概念作了一个宏观的介绍,了解了PCIe是一种封装分层协议(packet-based layered protocol),主要包括事务层(Transaction layer), 数据链路层(Data link layer)和物理层(Physical layer);
一:事务排序
与其他协议一样,当同一个通信等级(Traffic Class,TC)的多个事务(Transactions)同时通过同一个通道时,PCIe对这些事务设置了一些排序(Transaction Ordering)规则;
这样做的好处有以下几点:
-
保持与传统总线的兼容性。比如PCI,PCI-X等;
-
保证事务的完成具有准确性,并且按照设计人员的意愿完成;
-
避免死锁的状况发生;
-
最大限度的优化PCIe总线的传输效率。
注释:死锁是指两个以上的设备在访问临界资源时,相互等待对方释放这些资源,而无法访问这些资源的情况。
在PCIe总线上,只支持Strong Ordering传送规则,而在PCIe总线中增加了Relaxed Ordering(RO)和ID-based Ordering(IDO)传递方式;
Strong Ordering:
何为Strong Ordering?顾名思义,Strong就是很强壮,很彪悍的意思,Strong Ordering强制总线上的TLP按照先来后到的方式进行传递,一视同仁,不管是否有特殊情况,军不允许插队和绿色通道,但是事情总有轻重缓急,对于一些紧急的状况,这个强制规则难免会影响到总线的传递效率和用户体验;
我们看下面一个例子:
-
所有的TLPs类型统一编号;
-
发送端VC buffer有8个待传输的TLPs,依次编号为#1~8,这8个TLPs分为三类:
Posted:2, 4, 7;
Non-Posted: 1, 5;
Completions: 3, 6, 8;
-
接收端对应的VC buffer如上图,其中,Non-Posted buffer已满,而Posted、Completions buffer则仍有可用空间;
此时,接收端Non-Posted buffer已满,TLP 1,5则需要暂停发送。由于这8个TLPs属于同一VC,需要按照Strong-Ordering规则排序。所以TLP 2,3,4对应接收端VC buffer即使有可用空间,也必须等TLP 1传输完成之后才能发送。
这不就是浪费时间嘛,浪费别人的时间,就等于谋杀呀~Strong-Ordering太不厚道咯~~~
Relaxed Ordering(RO):
相比PCI,PCIe则深得中庸之道,更加善解人意,PCIe支持的Relaxed Ordering的传递规则不会要求TLPs严格遵守先来后到,也意味着根据轻重缓急找到最佳的方案,提高数据的传输效率。
不过,Relaxed Ordering是有条件的,因为每个TLP只能对应一个TC(通信等级),而这个TC有只能对应唯一一个VC(虚拟通道),所以说:
-
VC相同的TLPs遵循Relaxed Ordering规则,
-
VC不同的TLPs则没有事务排序的要求,不必遵循Relaxed Ordering规则。
VC相同的TLPs需要遵循的排序规则具体如下表:
先解释一下表格中的Yes, Y/N, No对应的含义:
Yes: 代表第二个事务必须在第一个事务之前通过,也就是强制性"超车";
Y/N: 没有排序要求;
No: 代表第二个事务绝对不允许在第一个事务之前通过,也就是"超车"违法.
我们解析一下表格中的A2b, B2, C2b, D2b的内容来阐述一下Relaxed-Ordering的效果:
A2b: 当RO=1, 也即Enable Relaxed-Ordering规则。此时,Memory Writes or Messages被允许超车之前的Memory Writes or Messages而抢先通过;
B2: 无论RO bit是否被置起来, Read Requests均不被允许超车之前的Memory Writes or Messages而抢先通过;
C2b: 当RO=1, IO writes和Configuration writes被允许超车之前的Memory Writes or Messages而抢先通过;
D2b: 当RO=1, Competitions被允许超车之前的Memory Writes or Messages而抢先通过;
ID-based Ordering(IDO):
IDO的模型是在PCIe V2.1版本后新增的功能,该模型引入了”数据流“(stream)的概念,即:
-
相同数据源发送的TLPs属于同一数据流;
-
不同数据源发送的TLPs属于不同的数据流;
IDO模型允许不同数据流的TLPs之间不必遵循事务排序的约定;
我们来看个例子:
-
设备1发送了Posted Write Request, 但是,此时Write Buffer已处于满的状态,所以Posted-Write被锁定在Switch。
-
随后,设备3发送了Non-Posted Read Request, 通过Switch时,正好撞到了上面表格B2所指规则(B2: 无论RO bit是否被置起来, Read Requests均不被允许超车之前的Memory Writes or Messages而抢先通过;), 所以,Read request同样被锁定在Switch。
此时,就要靠IDO这位大神出手咯~
依照IDO模型的思想,Posted Write request和Read request的数据源不一样,可以不遵循事务排序规则。
所以,当PCIe总线enable IDO功能时,Read request可以很开心的通过Switch,这个时候,Posted Write只有羡慕嫉妒恨的份儿咯~~~