发送带有'的BUF;MSG_zeropy';标志和';所以"零拷贝"';内核4.14中的选项的行为比非_zerocpy更糟糕
我尝试了内核4.14的零拷贝,下面是关于内核4.14中零拷贝的详细信息 [1] () 我在squid中测试了它,squid是一个缓存代理,我的代码和上面的有点不同。我使用epoll处理zerocopy并复制磁盘文件以发送到客户端。 当套接字可写时,我使用如下函数发送带有'的BUF;MSG_zeropy';标志和';所以"零拷贝"';内核4.14中的选项的行为比非_zerocpy更糟糕,c,linux,caching,linux-kernel,zero-copy,C,Linux,Caching,Linux Kernel,Zero Copy,我尝试了内核4.14的零拷贝,下面是关于内核4.14中零拷贝的详细信息 [1] () 我在squid中测试了它,squid是一个缓存代理,我的代码和上面的有点不同。我使用epoll处理zerocopy并复制磁盘文件以发送到客户端。 当套接字可写时,我使用如下函数 send(fd, buf, sz, MSG_ZEROCOPY); //sz=16KB, 32KB 我还按照如下方式处理EPOLLERR,以释放分配的buf recvmsg(fd, &msg, MSG_ERRQUEUE) 但是
send(fd, buf, sz, MSG_ZEROCOPY); //sz=16KB, 32KB
我还按照如下方式处理EPOLLERR,以释放分配的buf
recvmsg(fd, &msg, MSG_ERRQUEUE)
但是我发现fd经常被EPOLLERR唤醒,所以每次send调用后我都会调用recvmsg,否则cpu就会运行得很高。然后我使用curl向squid代理发出请求,squid代理具有请求的缓存
foreach -c 400 -w 4 'curl -o /dev/null -s -w "%{time_connect} %{time_total} %{speed_download}\n" http://160MB.html -x 192.168.1.20:3128 -H "Pragma: "'
但结果表明
非零拷贝代码更快。cpu热功能分布如下:
non_zero_copy: %Cpu1 : 21.9 us, 77.1 sy, 0.0 ni, 0.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.3 st
32.52% [kernel] [k] copy_user_enhanced_fast_string
8.73% libc-2.17.so [.] __memcpy_ssse3_back
6.36% [kernel] [k] iowrite16
3.97% [kernel] [k] do_syscall_64
3.60% [kernel] [k] _raw_spin_unlock_irqrestore
3.25% libc-2.17.so [.] __memset_sse2
2.74% [kernel] [k] find_get_entry
2.03% libpthread-2.17.so [.] pthread_cond_wait@@GLIBC_2.3.2
1.66% [kernel] [k] tcp_sendmsg_locked
1.44% [kernel] [k] generic_file_read_iter
0.84% [kernel] [k] finish_task_switch
0.80% libc-2.17.so [.] epoll_ctl
0.78% [kernel] [k] __fget
0.78% [kernel] [k] get_page_from_freelist
0.77% [kernel] [k] sock_poll
0.71% [kernel] [k] skb_release_data
0.69% libpthread-2.17.so [.] __pthread_disable_asynccancel
0.64% [kernel] [k] sys_epoll_ctl
0.62% [kernel] [k] __audit_syscall_exit
zero_copy: %Cpu1 : 35.8 us, 63.9 sy, 0.0 ni, 0.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
9.41% [kernel] [k] do_syscall_64
8.57% [kernel] [k] copy_user_enhanced_fast_string
7.79% [kernel] [k] _raw_spin_unlock_irqrestore
7.55% libc-2.17.so [.] 0x00000000000f7d13
6.70% [kernel] [k] ep_send_events_proc
5.11% [vdso] [.] __vdso_gettimeofday
4.73% libc-2.17.so [.] __memset_sse2
4.16% [kernel] [k] pvclock_clocksource_read
3.66% libc-2.17.so [.] __memcpy_ssse3_back
2.02% [kernel] [k] tcp_poll
1.95% [kernel] [k] iowrite16
1.93% squid [.] comm_select
1.73% [kernel] [k] find_get_entry
1.57% [kernel] [k] sock_poll
1.54% [kernel] [k] __fget
1.53% [kernel] [k] select_estimate_accuracy
1.41% squid [.] getCurrentTime
0.86% [kernel] [k] ktime_get_ts64
0.84% [kernel] [k] ep_poll
0.83% [kernel] [k] ep_scan_ready_list.isra.13
0.81% libpthread-2.17.so [.] pthread_cond_wait@@GLIBC_2.3.2
0.73% [kernel] [k] fput
0.71% [kernel] [k] __audit_syscall_entry
0.71% [kernel] [k] __audit_syscall_exit
0.70% [kernel] [k] mutex_lock
0.66% [kernel] [k] _raw_spin_lock_irqsave
0.59% libc-2.17.so [.] __libc_disable_asynccancel
0.57% squid [.] statHistCount
有人和我做过同样的测试吗?为什么我的测试结果与上面pdf中文章的结果不一样。您是在尝试环回零拷贝还是真正的网卡?请务必先检查文档/网络/msg_zerocopy.rst 环回 发送到本地套接字的数据可以无限期排队,如果 进程不读取其套接字。未绑定通知延迟不可用 可以接受。因此,使用MSG_ZEROCOPY生成的所有数据包 循环到本地套接字的复制将导致延迟复制。这 包括在数据包套接字(如tcpdump)和tun设备上循环 另外,从实现的角度来看,您的网卡似乎已经启用了tx分散收集fraglist。在
ethtool-k
中检查它
zc = sk->sk_route_caps & NETIF_F_SG;
if (!zc)
uarg->zerocopy = 0;
enum {
NETIF_F_SG_BIT, /* Scatter/gather IO. */
我什么也不修改,只是将测试从虚拟机移动到真实机:函数uu zeropcopy_sg_from_iter,它从未在虚拟机中出现,而是在真实机中出现
ZERO_COPY: (in real machine)
%Cpu1 : 17.8 us, 34.9 sy, 0.0 ni, 47.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
13903 squid 20 0 147236 45196 5860 R 52.2 0.1 0:15.65 squid
18.42% libc-2.17.so [.] __memcpy_ssse3_back
17.32% [kernel] [k] copy_user_generic_string
2.79% [kernel] [k] syscall_return_via_sysret
2.09% [unknown] [k] 0xfffffe800003201e
1.91% [kernel] [k] gup_pgd_range
1.21% [kernel] [k] generic_file_read_iter
1.20% [kernel] [k] _raw_spin_lock
1.05% [kernel] [k] sock_poll
1.04% [kernel] [k] sys_epoll_ctl
1.02% [kernel] [k] __schedule
0.97% [kernel] [k] __audit_syscall_entry
0.93% [kernel] [k] __zerocopy_sg_from_iter
and i make a comparisonwith NO_ZEROCOPY in real machine
%Cpu1 : 11.4 us, 46.8 sy, 0.0 ni, 41.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
13988 squid 20 0 115948 15228 5784 R 57.5 0.0 0:31.99 squid
33.27% [kernel] [k] copy_user_generic_string
9.62% libc-2.17.so [.] __memcpy_ssse3_back
2.34% [kernel] [k] syscall_return_via_sysret
1.80% [unknown] [k] 0xfffffe800003201e
1.35% [kernel] [k] tcp_sendmsg_locked
1.18% [kernel] [k] generic_file_read_iter
NO_ZEROCOPY ZERO_COPY
cpu 62.9 53.6
cpu 53.6 43.3
cpu 46.8 34.9
谢谢,你说得对。我在虚拟机中进行测试,当我将测试移动到真实的机器上时,我可以得到正确的结果。而且函数堆栈也与“零拷贝”关联,但在虚拟机中,函数堆栈与“零拷贝”不关联。我测试192.168.1.70到192.168.1.20之间的请求,两个虚拟机在同一台实机上。但是tx散射聚集fraglist选项关闭(已修复)您好,您能详细说明一下您测试MSG_ZERO copy的步骤吗?。我正在尝试测试相同的内容,我得到一个错误,如下所示执行“/MSG_ZERO copy”失败:没有这样的文件或目录[1]+Exit 1ip netns exec cli“${BIN}”-${ip}”-i p4p4p4-t2-c2-S“${SADDR}”-D“${DADDR}”{ARGS}-r“${RXMODE我没有在内核的示例中测试msg_zerocopy,而是使用squid源代码中的函数