0

我的系统是 CentOS 8,内核为:4.18.0-240.22.1.el8_3.x86_64,我使用的是 DPDK 20.11.1。核心:

我想以优化的方式计算往返时间,以便从机器 A 发送到机器 B 的数据包从机器 B 环回到 A 并测量时间。完成此操作后,机器 B 运行 DPDK 转发应用程序(如 testpmd 或 l2fwd/l3fwd)。

一种方法是使用 DPDK pktgen 应用程序(https://pktgen-dpdk.readthedocs.io/en/latest/),但我找不到它以这种方式计算往返时间。虽然 ping 是另一种方式,但是当机器 B 从机器 A 接收到 ping 数据包时,它必须处理数据包然后响应机器 A,这会增加一些周期(这在我的情况下是不希望的)。

接受计算这个时间的建议和方法。此外,比较基于 DPDK 的应用程序与非 DPDK 设置的 RTT(往返时间)的基准也会提供更好的比较。

编辑:有一种方法可以在 DPDK pktgen 中启用延迟。任何人都可以分享一些有关如何计算此延迟及其含义的信息(我在文档中找不到有关页面延迟的可靠信息。

4

2 回答 2

1

通过接口发送和接收数据包的理想延迟方法是在机器 A NIC 端口上设置外部环回在此处输入图像描述设备。这将确保发送的数据包在没有任何处理的情况下被接收回同一个 NIC。

下一个最佳选择是启用Internal Loopback,这将确保所需的数据包转换为 PCIe 有效负载和 DMA 到硬件数据包缓冲区。基于 PCIe 配置,数据包缓冲区将与 RX 描述符共享,从而导致发送数据包的 RX。但是对于这个需要一个网卡

  1. 支持内部环回
  2. 并且可以抑制 Loopback 错误处理程序。

另一种方法是使用任一PCIe port to port cross connect. 在 DPDK 中,我们可以为 core-A 上的 port-1 运行 RX_BURST,为 core-B 上的 port-2 运行 RX_BURST。这将确保几乎准确的往返时间。

注意:较新的硬件支持doorbell机制,因此在 TX 和 RX 上,我们可以启用硬件向驱动程序/PMD 发送回调,然后可用于获取硬件辅助的 PTP 时间戳以实现纳秒级精度。

但在我的建议中,使用外部(机器 B)是不可取的,因为

  1. 根据传输介质的质量,延迟会有所不同
  2. 如果必须将机器 B 配置为理想设置(几乎 0 延迟)
  3. 即使物理配置相同,机器 A 和机器 B 也需要维护并在相同的热设置下运行,以实现正确的时钟。
  4. 机器 A 和机器 B 都必须使用相同的 PTP 主控器来同步时钟。
  5. 如果使用 DPDK,要么修改 PMD,要么使用rte_eth_tx_buffer_flush确保数据包发送到 NIC

通过这些更改,可以创建一个虚拟 UDP 数据包,其中

  • 前 8 个字节应携带来自 Machine-A (T1) 的 tx_burst 之前的实际 TX 时间。
  • 第二个 8 字节由机器 B 在实际通过 rx_burst (2) 接收到 SW 中的数据包时添加。
  • 当 tx_burst 完成 (T3) 时,第三个 8 字节由 Machine-B 添加。
  • 当通过 rx-burst (T4) 实际接收到数据包时,在 Machine-A 中找到第四个 8 字节

有了这些Round trip Time = (T4 - T1) - (T3 - T2),其中 T4 和 T1 给出了来自机器 A 和 T3 的接收和传输时间,而 T2 给出了处理开销。

注意:根据处理器和代,无变体 TSC 可用。这将确保滴答rte_get_tsc_cycles声不会因频率和功率状态而变化。

[Edit-1] 如评论中所述

  1. @AmmerUsman,我强烈建议您编辑您的问题,以反映如何测量往返时间的真实意图,而不是 DUT 的 TX-RX 延迟?这是因为您指的是 DPDK 延迟统计/指标,但是用于测量同一 DUT 上 Rx-Tx 之间的最小/最大/平均延迟。
  2. DPDK 中的@AmmerUsman 延迟库是代表 TX-callback 和 RX-callback 之间差异的统计数据,不适用于您所描述的用例。根据 Keith 的解释,流量生成器发出的数据包应在有效负载上发送时间戳,接收应用程序应转发到同一端口。然后接收方应用程序可以测量接收到的时间戳和嵌入在数据包中的时间戳之间的差异。为此,您需要将其发送回与您的设置图不匹配的同一端口
于 2021-09-20T05:41:58.173 回答
1

这实际上取决于您要测量的往返行程类型。考虑以下时间戳:

  -> t1  -> send() -> NIC_A -> t2  --link--> t3  -> NIC_B -> recv() -> t4
host_A                                                              host_B
  <- t1' <- recv() <- NIC_A <- t2' <--link-- t3' <- NIC_B <- send() <- t4' 

你要测量t1' - t1吗?然后,只需编写一个小型 DPDK 程序,该程序在主机 A 上的每次发送/接收函数调用之前/之后存储 TSC 值。(在主机 b 上运行转发应用程序。)另请参见rte_rdtsc_precise()rte_get_tsc_hz()TSC 增量转换为纳秒.

对于非 DPDK 程序,您可以通过其他方式读出 TSC 值/频率。根据您的分辨率需求,您也可以只调用clock_gettime(CLOCK_REALTIME)其开销为 18 ns 左右。

这适用于单包传输rte_eth_tx_burst() 和单包接收——这对于您的目标应用程序来说不一定是现实的。对于较大的突发,您必须在第一次传输之前和最后一次传输之后使用获取时间戳,然后计算平均增量。


时间戳t2, t3, t2', t3'是(更严重的)NIC 提供的硬件传输/接收时间戳。

如果您想计算往返,t2' - t2那么您首先需要调整 NIC 的时钟(例如使用phc2ys),启用时间戳并获取这些时间戳。但是,AFAICS dpdk 通常不支持获取 TX 时间戳。

因此,当使用 SFP 收发器时,另一种方法是在 NIC_A 的 RX/TX 端安装无源光学 TAP,并将监控端口连接到支持接收硬件时间戳的数据包捕获 NIC。有了这样的设置,计算t2' - t2往返只需编写一个脚本,该脚本从您的 pcap 读取匹配数据包的时间戳并计算它们之间的增量。

于 2021-09-16T15:59:24.697 回答