如何使DPDK应用与NIC运行在同一NUMA节点?当前二者分属不同节点的问题咨询
老兄,你这情况我见得太多了——DPDK应用跑在NUMA节点0,网卡却在节点1,跨NUMA访问肯定会拖慢性能,DPDK的警告日志已经把问题说得明明白白了:rte_eth_dev_socket_id(port)返回1(网卡在节点1),rte_socket_id()返回0(应用线程在节点0)。下面给你几个靠谱的解决办法:
最直接的:把DPDK应用绑到NIC所在NUMA节点的CPU核上
启动DPDK应用时,用-l参数指定节点1的CPU核就行。比如你的服务器节点1对应的物理核是2、3,就这么启动:./your_dpdk_app -l 2-3要是你需要在代码里手动控制线程亲和性,也可以用
rte_eal_remote_launch把收发包的核心线程绑定到节点1的核上,确保线程和网卡的NUMA节点完全匹配。调整大页内存的NUMA分配策略
启动应用时加上--socket-mem参数,只给NIC所在的节点1分配大页内存,比如分配1024MB:./your_dpdk_app -l 2-3 --socket-mem 0,1024这样DPDK会优先在节点1上分配内存,避免跨NUMA的内存拷贝,进一步提升性能。
部分平台支持:调整NIC的NUMA亲和性
有些服务器可以通过BIOS或者系统工具(比如numactl)修改PCI设备的NUMA节点归属,但这个得看你的服务器硬件是否支持,不是所有机型都能这么操作。如果尝试的话,记得用root权限,操作前最好备份BIOS设置。
另外,你用来检测NUMA不匹配的这段代码写得挺到位,正好可以用来验证解决效果:
uint16_t port = 0; RTE_ETH_FOREACH_DEV(port) { if (rte_eth_dev_socket_id(port) >= 0 && rte_eth_dev_socket_id(port) != rte_socket_id()) { NSTK_LOG_WARN("Port %u is on remote NUMA node to polling thread. Performance will not be optimal, rte_eth_dev_socket_id: %u, rte_socket_id: %u", port, rte_eth_dev_socket_id(port), rte_socket_id()); } }
你之前看到的警告日志就是典型的NUMA不匹配提示:
Port 0 is on remote NUMA node to polling thread. Performance will not be optimal, rte_eth_dev_socket_id: 1, rte_socket_id: 0
按照上面的方法调整后,再跑一遍代码,应该就不会再出现这个警告了。
内容来源于stack exchange

