【问题标题】:Latency in ioreadioread 中的延迟
【发布时间】:2016-04-05 15:40:41
【问题描述】:

假设您有一个 PCIE 设备,它提供一个 BAR 和一个用 pci_alloc_consistent(..) 声明的 DMA 区域。 BAR 的标志表示不可预取、不可缓存的内存区域。

读取DMA区域延迟的主要原因是什么,同样,读取BAR延迟的原因是什么?

感谢您回答这个简单的问题:D!

【问题讨论】:

    标签: linux real-time drivers pci-e


    【解决方案1】:

    这闻起来有点像家庭作业,但我怀疑这些概念很多人都不太了解,所以我会添加一个答案。

    考虑这一点的最佳方法是考虑完成阅读需要发生什么。 CPU 和设备位于 PCIe 链路的不同侧。将 PCI-Express 视为迷你网络会很有帮助。每个链接都是点对点的(就像您的 PC 连接到另一台 PC)。也可能有中间开关(PCI 中的桥接器)。在这种情况下,就像您的 PC 连接到一个交换机,而交换机又连接到另一台 PC。

    因此,如果 CPU 想要读取自己的内存(您分配的“DMA”区域),它的速度相对较快。它有一个高速总线,旨在快速实现这一目标。此外,还内置了多层缓存,以使经常(或最近)使用的数据“靠近”CPU。

    但是如果 CPU 想要从设备中的 BAR 读取,CPU(实际上是与 CPU 集成的 PCIe 根联合体)必须组成一个 PCIe 读取请求,发送请求,并等待设备解码请求,访问 BAR 位置并发送回请求的数据。滴答滴答。您的 CPU 在等待此操作完成时什么也不做。

    这非常类似于从另一台计算机请求网页。您制定一个 HTTP 请求,发送它并等待 Web 服务器访问内容,制定一个返回数据包并将其发送给您。

    如果设备希望访问驻留在 CPU“中”的内存,则几乎完全相反。 (“直接内存访问”只是意味着它不需要中断 CPU 来处理它,但是 [这里的根复合体] 仍然负责解码请求,完成读取并发送回结果数据。)

    此外,如果 CPU 和设备之间存在中间 PCIe 交换机,则可能会增加额外的缓冲/排队延迟(就像网络中的交换机或路由器一样)。任何此类延迟都会加倍,因为它们是双向发生的。

    当然,PCIe 非常快,所以所有这些都在几纳秒内完成,但这仍然比“本地”读取慢几个数量级。

    【讨论】:

    • 吉尔感谢您的回答。我没有意识到 BAR 不是实际内存,它只是根复合体为设备生成 TLP 的地址,因此从 CPU 读取 BAR 始终是未发布的事情。有没有办法将 ioread 设置为不可中断,因为在大多数情况下读取需要 2us,但在某些情况下需要 15ms。这可能是任务抢占,因为它也在 HZ 值为 100 的区域(单任务隔离 cpu)。我会对 10usec 而不是 15ms 感到满意:D.
    • 单次读取 BAR 是不可中断的(至少在我从事过的任何架构上)。从 CPU 的角度来看,您只是在执行加载指令。在机器指令的中间不会识别中断。那么问题来了:时间去哪儿了?我首先要弄清楚延迟在哪一侧。可以在读取之前和之后读取时间戳计数器(或您的拱门上可用的任何东西),以了解实际 PCIe 事务需要多长时间才能完成——整个序列都禁用中断。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多