【DPDK】【CPU usage】DPDK应用如何计算当前系统的压力

本文探讨了DPDK应用在polling模式下如何估算系统压力,特别是fwd线程的真实负载。通过分析收包空转次数,提出了一个估算公式来计算DPDK收包空转时间和压力。此外,还讨论了多队列、无接管网卡队列、sleep策略和中断对负载估算的影响,以及如何通过监测网卡RX Ring中积存的数据包来预判流量过载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【前言】

  使用DPDK开发的朋友应该都了解使用dpdk的fwd线程的工作模式是polling模式,即100%轮询的方式去加速网络IO,这样我们在操作系统层面上来观察目标processer会发现usage一直为100%,但是这真的是系统的真实负载么?很显然并不是,本文给出一种方法来计算dpdk的fwd线程的真实负载的方法。

【场景】

  使用DPDK头痛的一点就是DPDK的fwd线程工作在polling模式,会直接消耗一整个processer的计算资源,有的时候为了性能考虑,往往还会给当前processer设置isolcpus,将当前processer从内核的CFS调度器中“剥离”出来,防止有其他的task被“不长眼”的CFS调度器调度到和fwd线程同一个processer上,出现context switch,引起性能下降。

  而工作在polling模式的fwd线程会出现非常蛋疼的一点就是面临“无法有效的感知当前processer的压力”的问题。查看操作系统的相关信息,会发现这个processer的usage一直处于100%,但是真实情况真的是这样么?并不是,在流量处于低谷的时候,这个processer往往会出现空转的情况,就是调用dpdk的api收包函数调100次,次次收包个数都是0,因为根本就没有流量,所以需要一种新的方法来计算使用dpdk fwd线程的负载情况。

  额外多说一点,为了防止fwd线程出现空转,目前有不同种方法来“尽量”解决这种空转问题,主流的通常有两种:

  1. 利用sleep函数,简单粗暴,结合内核的NAPI策略,设定一个期望收包个数值,当实际收包个数小于这个数值就判断当前流量不大,sleep一下。
  2. 利用dpdk的rsc中断来解决,由于uio驱动只有一个中断号,因此这种方法在uio驱动基本没法用,只能在vfio场景下用。

  当然怎么防止dpdk fwd线程出现空转的解决方法不是这篇文章想讨论的主题,我后续会写我个人的解决方案,本篇文章更多的会聚焦在如何估算负载情况。

【分析】

  这里首先说明一下,这个方法里面有一部分是来自于dpdk社区的一篇文章,由intel专家ilia所写,这里是文章原文地址,本文中会有不少部分来自于这篇文章原文,但是本篇文章在实际应用中仍然是有些地方需要注意的。

https://software.intel.com/en-us/vtune-cookbook-core-utilization-in-dpdk-apps

  接下来我会结合实际应用和ilia的文章来阐述怎么“估算”dpdk fwd线程的负载情况。

  先直接说结论:

在不同的流量压力下,dpdk fwd线程对某个网卡队列的收包行为实际上是存在一定的分布的

  这句话怎么理解呢?实际上这句话就是intel专家ilia那篇文章的主要思想。这句话完整的解释是这样的:

### DPDK绑定网口端口号的方法与必要性 #### 方法 在DPDK环境中,绑定网口端口号是一个常见的操作流程。通过命令行参数`-p`或者`--portmask`可以指定需要使用的物理网卡端口掩码[^1]。例如,在运行一个基于DPDK应用程序时,可以通过如下方式指定要接管的网口: ```bash ./your_dpdk_app -c 0x03 -n 4 -- -p 0x03 ``` 在此例子中,`-c 0x03`表示使用CPU核心0和1;`-n 4`指定了内存通道数为4;`-- -p 0x03`则表明启用端口0和端口1。 另外,对于某些测试工具如l2fwd或pktgen-dpdk来说,它们会自动识别已经由igb_uio/uio_pci_generic/vfio-pci驱动接管后的网卡,并分配相应的逻辑端口号给这些物理网卡[^2]。 #### 必要性 绑定具体的网口端口号是非常必要的,原因在于以下几个方面: 1. **资源管理**:明确告诉应用程序哪些网络接口将参与数据传输过程,这样有助于合理规划硬件资源利用情况。 2. **性能优化**:当多个处理器核参与到同一个任务当中时,精确控制哪个NIC连接到哪几个CPU core能够显著提升整体吞吐量并减少延迟[^4]。 3. **功能实现**:像L2转发(l2fwd)这样的应用场景里,只有明确了输入输出的具体位置才能正确构建数据流路径[^2]。 综上所述,无论是出于效率考虑还是功能性需求的角度来看,适当地设置端口映射关系都是不可或缺的一环。 ```python def bind_port(port_mask): """ Simulate binding ports based on given port mask. Args: port_mask (int): Port mask indicating which ports to enable. Returns: list: List of enabled ports. """ all_ports = [i for i in range(16)] # Assuming up to 16 possible ports enabled_ports = [] index = 0 while port_mask > 0: if port_mask & 1: enabled_ports.append(all_ports[index]) port_mask >>= 1 index += 1 return enabled_ports print(bind_port(int('0b0011', 2))) # Example usage with binary string '0b0011' ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值