tcp_autocork_cpu如何CPU绑定

联启 网络工具 19

本文目录导读:

tcp_autocork_cpu如何CPU绑定-第1张图片-电脑手机工具软件下载 - 免费实用工具合集 | 联启科技

  1. 理解:为什么不能直接绑定?
  2. 方法一:使用 taskset 绑定整个进程及其 TCP 连接
  3. 方法二:使用 cgroup cpuset 进行更细粒度的控制
  4. 方法三:禁用特定 CPU 上的 tcp_autocorking(通过 sysctl)
  5. 方法四:利用 SO_INCOMING_CPU 和 epoll 进行 socket-CPU 固定
  6. 方法五:使用 RPS(Receive Packet Steering)间接影响发送路径
  7. 最实用方案

在 Linux 网络栈中,tcp_autocorking 是一个内核特性(从 3.14 版本引入),它自动延迟小数据包的发送,以合并为更大的 TCP 段,从而减少网络开销。这个功能本身是全局内核行为,没有直接的 sysctl 或 per-socket 选项来将它绑定到特定 CPU

如果你希望控制这个功能在哪些 CPU 上生效,或者想让相关进程/连接固定到某个 CPU,有几种间接方法可以实现类似“CPU 绑定”的效果。


理解:为什么不能直接绑定?

tcp_autocorking 是 TCP/IP 协议栈在处理 tcp_sendmsg() 时的逻辑决策,它发生在发起系统调用的进程上下文中,这个功能的实际执行 CPU 就是进程当前运行的 CPU

所谓的“绑定”其实就是:

  • 让所有使用 TCP 连接的进程固定在你希望的 CPU 上
  • 或者,控制该功能的全局开关在某些 CPU 上被禁用

使用 taskset 绑定整个进程及其 TCP 连接

这是最直接的方法:将运行网络服务的进程绑定到固定 CPU

# 将 nginx 绑定到 CPU 0 和 1
taskset -cp 0,1 $(pgrep nginx)
# 或直接启动时绑定
taskset -c 0,1 /usr/sbin/nginx

效果:

  • 该进程的所有 sendmsg 系统调用都在指定 CPU 上执行
  • tcp_autocorking 决策也在该 CPU 上发生
  • 同时也会影响 CPU 缓存局部性,通常对性能有利

使用 cgroup cpuset 进行更细粒度的控制

如果你需要为不同进程组分配不同 CPU,cgroup 是更好的选择。

# 创建 cpuset 组
mkdir /sys/fs/cgroup/cpuset/myapp
echo "0-2" > /sys/fs/cgroup/cpuset/myapp/cpuset.cpus
echo "0" > /sys/fs/cgroup/cpuset/myapp/cpuset.mems
# 将进程加入
echo $PID > /sys/fs/cgroup/cpuset/myapp/cgroup.procs

这样所有相关 socket 操作都被限制在 CPU 0-2 上。


禁用特定 CPU 上的 tcp_autocorking(通过 sysctl)

tcp_autocorking 是全局开关(net.ipv4.tcp_autocorking = 1),你不能按 CPU 禁用,但可以用一个技巧:

  1. 在非目标 CPU 上将进程绑定(通过 irqbalance 或隔离 CPU)
  2. 然后在整个系统层面禁用它,仅让绑定的进程启用它

但这通常不推荐,因为失去了自动 cork 的优势。

更常见的是:

# 全局启用(默认)
sysctl -w net.ipv4.tcp_autocorking=1
# 若想禁用某些连接的 cork,在 socket 层面设置 TCP_NODELAY
# setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));

利用 SO_INCOMING_CPU 和 epoll 进行 socket-CPU 固定

对于监听 socket 接受的连接,你可以让其保持在与接受它的同一个 CPU 上

// 获取 socket 当前绑定的 CPU
int cpu = 0;
socklen_t len = sizeof(cpu);
getsockopt(fd, SOL_SOCKET, SO_INCOMING_CPU, &cpu, &len);
// 将线程绑定到该 CPU(使用 pthread_setaffinity_np 或 sched_setaffinity)
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(cpu, &cpuset);
pthread_setaffinity_np(pthread_self(), sizeof(cpuset), &cpuset);

这样,每个连接的 tcp_autocorking 处理会固定在接受它的 CPU 上。


使用 RPS(Receive Packet Steering)间接影响发送路径

虽然 RPS 影响的是接收路径,但它通过将软中断分散到不同 CPU,间接影响了后续发送的 CPU 选择:

echo f > /sys/class/net/eth0/queues/rx-0/rps_cpus
# 这里的 f 表示使用 CPU 0-3

但这对发送路径是间接的,不能精确控制 tcp_autocorking 的 CPU。


最实用方案

需求 做法
让某个服务(如数据库)的 TCP 发送固定到 CPU 2 taskset -c 2 service_program
让不同连接固定到不同 CPU SO_INCOMING_CPU + pthread_setaffinity_np
完全禁用 tcp_autocorking sysctl net.ipv4.tcp_autocorking=0
只想让某些 socket 不 cork 设置 TCP_NODELAY socket 选项

tcp_autocorking 本身没有 CPU 绑定机制,你只能通过绑定进程绑定 socket 到特定 CPU 来间接实现它的 CPU 亲和性。

标签: CPU绑定

抱歉,评论功能暂时关闭!