从零开始讲PCIe(10)——事务层介绍

news2024/11/28 17:36:15

一、事务层概述

        事务层在响应软件层的请求时,会生成出站数据包。同时,它也会检查入站数据包,并将其中包含的信息传递到软件层。事务层支持非发布事务的分割事务协议,能够将入站的完成数据包与之前传输的非发布请求相关联。该层处理的事务使用事务层数据包(TLPs,Transaction Layer Packets),这些事务可以分为四类请求:

  1. 内存(Memory)
  2. IO(Input/Output)
  3. 配置(Configuration)
  4. 消息(Messages)

        前面三类请求在PCI和PCI-X中已经支持,而消息是PCIe中特有的一种请求类型。一个事务被定义为:包含一个向目标设备发送命令的请求数据包,和目标设备返回的任何完成数据包的组合。表2-2列出了不同的请求类型。

二、事务层数据包(Transaction Layer Packet,TLP)

2.1 non-posted与posted

        在PCIe中,事务层通过这种分组方式有效地管理数据传输,并且能够处理来自不同源的各种请求。

        请求可以分为两类,如表格右列所示:non-posted 和 posted 请求。对于non-posted请求,发送方(Requester)会发送一个数据包,接收方(Completer)需要生成一个完成数据包(Completion packet)作为回应。你可能会发现这与PCI-X继承的分割事务协议类似。例如,任何读取请求(Read)都是 non-posted 的,因为请求的数据需要在完成数据包中返回。可能让人意外的是,IO写入(IO Write)配置写入(Configure Write)也是 non-posted 的,尽管这些请求在传输写入的数据时,它们仍然期望接收方返回一个完成数据包,确认写入的数据已经成功传输到目标设备并且没有发生错误。

        与此相对的是,内存写入(Memory Write)和消息(Message)是 posted 请求,这意味着目标设备不会返回完成数据包给发送方。posted 事务可以提升性能,因为发送方不必等待回复,也不需要处理完成数据包带来的额外开销。权衡之下,posted 事务的缺点是发送方不会收到写入是否成功或遇到错误的反馈。这种行为从PCI继承而来,仍然被认为是一种合理的做法,因为发生故障的可能性较小,而性能提升显著。尽管 posted 写入不需要完成数据包,它们仍然会参与数据链路层(Data Link Layer)的Ack/Nak协议,该协议确保数据包可靠传输。

        表2- 3列出了所有PCIe请求和完成数据包类型的列表。

2.2 TLP传输

        TLPs 起始于发送方的事务层,终止于接收方的事务层,如图 2-15 所示。  

        当 TLP 途经发送方的数据链路层以及物理层时,这两层分别会向数据包中 添加一些信息,接收方的数据链路层和物理层会分别根据发送方对应层所添加的 信息来进行校验,以此确认数据包是否在链路传输中依旧保持正确没有出错。 

2.3 TLP组包

        TLP(Transaction Layer Packet)数据包的组装过程如图2-16所示。在TLP通过链路传输时,不同部分的数据包由各层添加。为了便于理解数据包的构建过程,各部分以不同颜色标示:红色代表事务层,蓝色代表数据链路层,绿色代表物理层。

        Device Core 将 TLP 核心部分所需的信息发送到事务层。在事务层,每个TLP都会包含一个Header(头部),但是数据却不是必须的,例如读请求,就可以没有数据。事务层还可以选择添加 ECRC(End-to-End CRC)字段,这 个 ECRC 由事务层进行计算并附加在数据包的后面。ECRC 字段区域在通过发送方和接收方之间的任何服务点(service point,通常指的是 Switch 或者 Root 端口这些有 TLP 路由功能的地方)时都不改变,这使得目的端可以用它来验证在整个传输过程中都没有发生错误。

        在传输过程中,TLP的核心部分被传递到数据链路层,该层负责添加序列号(Sequence Number)和另一种CRC字段,称为链路CRC(LCRC)。LCRC由邻近的接收端用来检测错误,并将检测结果报告给发送端。LCRC用于确保每个通过链路发送的数据包无误传输。

        可能有人会疑问,如果LCRC已经验证了链路上的无误传输,为什么还需要ECRC呢?原因在于,数据包在路由设备内部的转发过程中可能会发生未被检查的错误。例如,数据包到达一个端口时会进行错误检查,然后根据路由信息发送到另一个端口,新的LCRC值会被重新计算并添加。而在端口间的内部转发过程中,错误不会被常规的PCIe协议检测到,因此ECRC在这种情况下非常有用。

        最终,数据包被传递到物理层,在该层中添加其他字符,用于告知接收端接下来会发生什么。在PCIe的前两代中,这些字符是添加到数据包开头和结尾的控制字符。在第三代中,控制字符不再使用,但会在数据块中附加其他比特,用于传递关于数据包的必要信息。然后,数据包经过编码,并通过链路上的所有可用通道进行差分传输。

2.4 TLP解包

        当接收端看到传入的TLP比特流时,它需要识别并移除之前添加的部分,以恢复发送端核心部分请求的原始信息。如图2-17所示,物理层首先验证TLP数据包中的起始和结束字符或其他字符是否正确,并移除它们,然后将剩余的TLP传递给数据链路层。数据链路层会首先检查链路CRC(LCRC)和序列号是否有错误。如果未发现错误,数据链路层会移除这些字段并将数据包传递给事务层

        如果接收端是一个交换机,事务层会评估数据包,从TLP的头部提取路由信息,确定数据包应该转发到哪个端口。即使交换机不是目标设备,它仍可以检查并报告ECRC错误,但它不能修改ECRC,以便目标设备也能检测到此类错误。如果目标设备具备检查ECRC的能力且ECRC功能已启用,它可以检测ECRC错误。

        如果这是目标设备且没有发现错误,ECRC字段将被移除,剩余的头部和数据部分将被传递到软件层,供进一步处理。这样,接收端可以恢复并处理原始的事务请求或完成信息。

三、Non-Posted 事务

3.1 普通读(Ordinary Reads)

        普通读取请求的过程如图2-18所示,展示了一个从终端设备(Endpoint)发送到系统内存的内存读取请求(MRd)。内存读取请求中的一个重要部分是目标地址。内存请求的地址可以是32位或64位,这个地址决定了数据包的路由。在此例子中,请求通过两个交换机进行路由,最终被转发到目标设备,这里目标是RC。当RC解码该请求并识别到数据包中的地址指向系统内存(memory)时,它会获取所请求的数据。

        为了将数据返回给请求方,RC端口的事务层(Transaction Layer)会根据需要生成多个完成数据包(Completions,CplD),以便将所有请求的数据传递给请求方。PCIe中单个数据包的最大有效负载是4KB,但很多设备的设计使用的负载通常小于4KB,因此,如果请求的数据量较大,可能需要多个完成数据包才能返回所有数据。

        完成数据包(Completions,CplD)也包含路由信息,用于将数据包返回给发起请求的设备。请求方在最初的请求中包含了一个“返回地址”,以便完成数据包能够准确送达。这个“返回地址”就是请求方的设备ID(Device ID),它由三个部分组成:系统中的PCI总线号、该总线上的设备号、以及该设备内的功能号,统称为BDF(Bus, Device, Function)。这个BDF信息就是完成数据包在返回时使用的路由信息。

        如同在PCI-X中一样,请求方可能同时处理多个分割事务,因此必须能够将收到的完成数据包与相应的请求关联起来。为此,原始请求中添加了一个唯一标识的值,称为Tag。这个Tag在每个请求中都是独特的,完成方会将该Tag复制到完成数据包中,使请求方能够快速识别这个完成数据包对应的是哪个请求。

        此外,完成方还可以通过在完成状态字段中设置特定位来指示错误条件。这些错误信息可以让请求方大致了解问题出在哪里,但如何处理这些错误将由软件决定,这部分超出了PCIe规范的范围。

3.2 锁定读(Locked Reads)

        锁定内存读取(Locked Memory Reads)是用于支持原子读-修改-写操作的一种事务类型。这类操作主要用于处理器执行不可中断的任务,例如测试和设置信号量。当测试和设置操作正在进行时,其他对该信号量的访问都会被阻止,以避免产生竞争条件(race condition)。为了实现这种互斥,处理器使用锁定指示器(例如在并行前端总线上使用一个独立的引脚)来防止其他事务在锁定事务完成之前进行。

        这种锁定机制最早在PCI规范中提出,原因是当时的规范编写者预计PCI有可能取代处理器总线,因此在PCI规范中加入了处理器在总线上可能需要执行的操作(如锁定事务)的支持。不过,PCI在实践中很少被用作处理器总线,因此大部分处理器总线支持功能最终被移除。但锁定周期仍被保留下来,以支持少数特殊情况,PCIe也将这一机制向后兼容,主要用于遗留设备(Legacy Devices)的支持

        为了加速锁定事务的逐步淘汰,新的PCIe设备被禁止接受锁定请求,只有那些自我识别为遗留设备的设备可以合法地处理锁定请求。图2-19中的示例展示了一个请求方如何发起锁定请求(MRdLk)。根据定义,这类请求只能来自CPU,因此在PCIe中,只有根端口(Root Port)会发起锁定请求。锁定请求会通过目标内存地址在拓扑结构中路由,最终到达遗留终端(Legacy Endpoint)。当数据包在各个路由设备(称为服务点)中传递时,数据包的出口端口将被锁定,意味着在路径解锁之前,任何其他数据包都无法沿该方向传递。

        这种锁定机制确保了关键事务在整个系统中可以安全地执行,而不会受到其他事务的干扰。

        当完成方(Completer)收到锁定请求包并解码其内容后,它会收集所需的数据并生成一个或多个带有数据的锁定完成数据包(Locked Completions)。这些完成数据包使用请求方ID进行路由,返回给请求方。完成数据包经过的每个出口端口也会被锁定,直到路径完成数据包的传输。

        如果完成方在处理过程中遇到问题,它将返回一个没有数据的锁定完成数据包(因为原始的读取请求应该会返回数据,如果没有数据就意味着出现了问题),并且状态字段会指示该错误的相关信息。请求方接收到这个完成数据包后,会明白锁定操作没有成功,这意味着事务将被取消,后续该如何处理将由软件决定。

        这一机制确保了在事务出现问题时,系统能够及时捕捉到错误并采取适当的措施,而不会继续进行有潜在问题的操作。

3.3 IO 和配置写(IO and Configuration Writes)

        IO和配置写入(IO and Configuration Writes)是一种 non-posted 事务。图2-20展示了一个non-posted 的IO写入事务。与锁定请求类似,IO周期也只能合法地指向遗留终端(Legacy Endpoint)。请求包通过交换机,基于IO地址进行路由,直到到达目标终端。

        当完成方(Completer)收到请求后,它会接受数据,并返回一个不带数据的完成数据包,确认接收到了请求包。完成数据包的状态字段会报告是否发生了错误,如果发生了错误,请求方的软件将负责处理。如果完成数据包报告没有错误,请求方就知道写入的数据已经成功传送到目的地,接下来可以继续执行目标设备的下一步指令。

        这种 non-posted 事务写入的主要动机是:不同于内存写入,单单知道数据将在某个时间点到达目的地还不够。相反,后续的操作逻辑上不能进行,直到确认数据已经成功写入。因此,non-posted 写入主要来自处理器,用于确保关键操作顺序的执行。

四、Posted Writes

4.1 Memory Writes

        内存写入(Memory writes)始终是posted requests,即不会收到完成数据包。一旦请求发送后,请求方(Requester)不会等待任何反馈,就可以继续处理下一个请求,这样也不会浪费时间或带宽来传输完成数据包。

        如图2-21所示,内存写入请求通过目标内存地址在系统中进行路由,最终到达完成方(Completer)。一旦链路成功发送了请求,该事务在该链路上就已完成,链路可以开始处理其他数据包。最终,完成方接受数据,该事务才算真正完成。

        当然,这种方法的一个折衷是,由于没有发送完成数据包,因此请求方不会收到错误报告。如果完成方遇到错误,它可以记录错误并向RC发送一个消息,通知系统软件发生了错误,但请求方不会直接看到这些错误。这种方式虽然牺牲了错误报告的能力,但在没有出错的情况下,极大地提高了数据传输效率。

4.2 Message Writes 

        与之前讨论的请求不同,消息(Messages)有多种可能的路由方式,消息中的一个字段会指示应该使用哪种路由方法。例如,有些消息是针对特定完成方的发布写入请求,有些是从RC广播到所有终端设备的广播消息,还有一些是从终端设备发送并自动路由到RC的消息。

        在PCIe中,消息非常有用,它们有助于实现减少引脚数量的设计目标。通过消息,可以消除PCI中用于报告中断、功率管理事件和错误的旁路信号,因为这些信息可以通过正常的数据路径以数据包的形式传输。这大大简化了硬件设计,同时提高了系统的灵活性和效率。

五、QoS

        服务质量(Quality of Service, QoS)是PCIe从设计之初就考虑到的一个特性,特别是为了支持诸如流媒体音频或视频等对时间敏感的应用场景。在这些应用中,数据的及时交付至关重要。为了实现QoS,PCIe引入了一些关键机制:

  1. 首先,每个数据包由软件分配优先级,这通过在数据包中设置一个3位的字段流量类别(Traffic Class, TC)来实现。通常来说,较高的TC编号表示该数据包在系统中拥有更高的优先级。
  2. 其次,硬件为每个端口内置了多个缓冲区,称为虚拟通道(Virtual Channels, VC)。数据包会根据其TC编号被放置到适当的虚拟通道中。
  3. 第三,既然每个端口有多个缓冲区同时准备传输数据包,系统需要使用仲裁逻辑来选择从哪个虚拟通道发送数据包。
  4. 最后,在多个输入端口争夺一个输出端口的虚拟通道时,端口仲裁(Port Arbitration)机制负责选择哪一个输入端口优先。这种仲裁可以是硬件分配的,也可以由软件编程控制。

        这些硬件机制必须协同工作,才能使系统根据不同数据包的优先级进行处理,从而实现QoS。如果系统被正确编程和配置,它甚至可以为特定路径提供保证服务(Guaranteed Service),确保流量具有确定的延迟和带宽。

        例如,图2-22展示了一个视频摄像头和SCSI设备同时向系统DRAM传输数据的场景。视频数据具有时间敏感性,如果传输路径的带宽跟不上摄像头的需求,视频帧将被丢弃,导致捕捉的视频看起来不流畅。相比之下,SCSI数据传输的时间要求不那么严格,只要确保数据没有错误即可。因此,当视频数据包和SCSI数据包同时需要传输时,系统应该优先传输视频数据包,以确保服务质量。

六、 事务排序(Transaction Ordering)

        在虚拟通道(VC)内,数据包通常按照到达的顺序依次传输,但也有一些例外情况。PCI Express协议继承了PCI事务排序模型,包括PCI-X架构中添加的支持松散排序的情况。这些排序规则确保使用相同流量类别(TC)的数据包能够按照正确的顺序通过系统拓扑,避免潜在的死锁或活锁问题。值得注意的是,由于排序规则仅适用于同一虚拟通道内的数据包,而不同流量类别的包可能不会映射到同一个虚拟通道,因此,使用不同TC的数据包在软件看来不存在排序关系。这种排序控制是在事务层的虚拟通道内保持的,从而确保系统内不同优先级的数据流能够正确传输。

七、流量控制(Flow Control)

        串行传输通常使用的一种协议要求发送方只有在确认接收方有足够的缓冲空间时,才可以发送数据包给它的邻居。这种机制减少了总线上不必要的性能浪费事件,比如在PCI中常见的断开和重试操作,从而消除了这一类问题。与此相对的折衷是,接收方必须足够频繁地报告其缓冲区的空间情况,以避免不必要的停滞,而这种报告本身也会占用一些带宽。

        在PCIe中,这种报告通过数据链路层数据包(Data Link Layer Packets, DLLPs)来完成,避免了使用事务层数据包(TLPs)可能引发的死锁问题。在某些情况下,TLPs可能无法发送或接收缓冲区大小更新,因为接收方的缓冲区已满,而DLLPs可以在任何缓冲状态下发送和接收,从而避免了这一问题。

        这种流控制协议在硬件层面自动管理,对软件是透明的,因此,软件无需干预就能确保高效的流控制。

        如图2-23所示,接收端包含用于存储接收到的TLP(事务层数据包)的虚拟通道(VC)缓冲区。接收端通过流控制DLLP(数据链路层数据包)向发送端通告这些缓冲区的大小。发送端会跟踪接收端VC缓冲区中的可用空间,只有在接收端有足够空间时,发送端才允许发送更多数据包。当接收端处理完TLP并从缓冲区中移除它们时,接收端会定期发送流控制更新DLLP,以便让发送端及时了解可用的缓冲空间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2192227.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

开发人员智能助手

据说AI可以代替开发人员,目前看暂时不用担心,不仅不担心,还要主动使用它。 过去有了问题需要自己各网站搜索,真真假假的东西太多,很难找到正确答案,现在可以问智能体了: 1、JAVA开发大师 htt…

【C++】输入输出缺省参数

大家好,我是苏貝,本篇博客带大家了解C的缺省参数,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️ 目录 一. 输入&输出二. 缺省参数1 缺省参数概念2 缺省参数分类a. 全缺省参数b. 半缺省参数…

Top4免费音频剪辑软件大比拼,2024年你选哪一款?

现在我们生活在一个数字化的时代,音频内容对我们来说很重要。不管是给自己拍的视频配背景音乐、整理开会时的录音,还是自己写歌,有个好用的音频剪辑软件都特别重要。今天,我要给大家介绍几款特别好用的音频剪辑软件免费的&#xf…

Vue82 路由器的两种工作模式 以及 node express 部署前端

笔记 对于一个url来说,什么是hash值?—— #及其后面的内容就是hash值。hash值不会包含在 HTTP 请求中,即:hash值不会带给服务器。hash模式: 地址中永远带着#号,不美观 。若以后将地址通过第三方手机app分享…

教育技术革新:SpringBoot在线教育系统开发

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及,互联网成为人们查找信息的重要场所,二十一世纪是信息的时代,所以信息的管理显得特别重要。因此,使用计算机来管理微服务在线教育系统的相关信息成为必然。开…

【性能测试】使用JMeter性能工具做测试的基本过程及案例分析

前言 通过精心设计的性能测试,我们不仅能够了解服务端的综合效能与承载极限,更能前瞻性地评估现有业务架构在面对当前运营需求及未来业务扩张时的适应性与弹性,从而精准规划服务配置的优化路径。 使用jmeter一般用于以下两种类型的性能测试…

Dart基础入门

Dart 是一种由 Google 开发的开源编程语言,它可以用来构建服务器、Web 应用和移动应用。Dart 语言设计得既现代化又易于学习,它支持面向对象编程(OOP)、函数式编程风格,并且具有类似于 Java 或 C# 的语法。Dart 语言和…

性能测试学习2:常见的性能测试策略(基准测试/负载测试/稳定性测试/压力测试/并发测试)

一.基准测试 1)概念 狭义上讲:就是单用户测试。测试环境确定后,对业务模型中的重要业务做单独的测试,获取单用户运行时的各项性能指标。 广义上:是一种测量和评估软件性能指标的活动。可以在某个时刻通过基准测试建立…

[MASM] masm32的下载及详细安装使用过程(附有下载文件)

目录 下载 配置环境 编译 链接 masm的安装和环境配置 下载链接在文末 下载 下载安装包后复制到虚拟机win7系统的桌面 win7安装到虚拟机的步骤: [win7] win7系统的下载及在虚拟机中详细安装过程(附有下载文件)-CSDN博客 双击压缩包&…

微信消息转发(微信消息转发方案的取舍)

机构可能会有很多的粉丝群,老师有很多家长群,比如发送通知 如果一个个的群发送那么就很繁琐。所以就有一键群发的需求。只需要在一个群发送内容主动同步到其他群。 微信消息转发方案取舍 方案1. 因为微信有本地数据库SQLite, 消息会保存到本…

Redis安装RedisBloom插件

Redis安装RedisBloom插件 1. 下载RedisBloom2. 安装RedisBloom3. Redis 安装RedisBloom4. 验证是否安装成功5. 其他安装方法5.1 使用 Docker 安装 RedisBloom5.2 通过 RedisStack 安装 RedisBloom 是一个 Redis 模块,它提供了一种高效的方式来存储和检索大数据集中的…

频繁full gc问题排查及解决

为什么我们要对频繁full gc的情况进行处理---》频繁full gc会导致stw,影响用户体验。 (1)先进行问题的排查 如果频繁full gc 会报警,公司有自己的监控平台,可以查看full gc的情况 如果公司没有自己的监控平台&#…

爬虫案例——爬取情话网数据

需求: 1.爬取情话网站中表白里面的所有句子(表白词_表白的话_表白句子情话大全_情话网) 2.利用XPath来进行解析 3.使用面向对象形发请求——创建一个类 4.将爬取下来的数据保存在数据库中 写出对应解析语法 //div[class"box labelbo…

【实战篇】自增主键为什么不是连续的?

背景 由于自增主键可以让主键索引尽量地保持递增顺序插入,避免了页分裂,因此索引更紧凑。 之前我见过有的业务设计依赖于自增主键的连续性,也就是说,这个设计假设自增主键是连续的。但实际上,这样的假设是错的&#…

Linux高阶——Github本地仓库与云端仓库关联

1、安装代理软件 steam 选择Github和系统代理模式,一键加速即可 2、 安装Git 3、访问Github网站,创建新用户 4、Github探索 (1)Explore探索标签 (2)工程结构 用户名/仓库名 自述文件,用markdo…

C语言复习概要(三)

本文 使用Visual Studio进行调试的技巧与函数递归详解1. 引言2. Visual Studio 调试技巧2.1. 断点的使用2.1.1. 基本断点示例:设置基本断点 2.1.2. 条件断点示例:条件断点 2.2. 逐步执行代码示例:逐步执行代码 2.3. 监视变量使用监视窗口 2.4…

希捷8T硬盘exfat变0字节的恢复方法

最近流行的3.5寸大容量台式硬盘移动盒子是一种性价比较高的组合,为了方便如涉及到跨平台(win和mac),大多数此类组合选择了exfat文件系统。下边这个案例就是我们经常遇到的exfat变0字节。 故障存储: ST8000HKVS002 8T/exfat 文件…

STM32F407 HAL库单通道ADC采集并串口打印电压值

本文将介绍如何使用STM32F407的HAL库实现单通道ADC采集,并通过串口将采集到的电压值打印出来。具体地,我们将使用ADC1读取通道5(对应引脚PA5),并将转换后的电压值用串口1发送到串口助手上进行显示。 一、开发环境 硬件…

类和对象的学习1

类和对象的学习1 [TOC](类和对象的学习1一、类的定义1.类定义格式2.访问限定符 二、实例对象1.实例3.对象大小4. this指针5.⾯向对象三⼤特性“封装、继承、多态”中的封装) 一、类的定义 1.类定义格式 1.1 class为定义类的关键字,Stack为类的名字,{}中…

第十五周周报

目录 摘要Abstract1 LSTM模型实战1.1 数据处理1.2 LSTM模型的搭建1.3 数据的预测和可视化 2 transformer(上)2.1 Transformer 结构2.2 Transformer 编码器 总结 摘要 本周的工作内容主要分为两个部分,第一部分是使用LSTM模型预测股票市场数据…