golang 在 Windows 下,网络 io 资源消耗似乎比比 Linux 高一些

50 天前
 seWindows
有一个网络处理程序,大量小包吞吐,直接使用 goroute 开新协程后 io.copy 直接处理后续接口。go 确实写的很快。

go1.23+编译

Linux 虚拟机下跑满虚拟网卡 100M 后,cpu 占用 4%,换成 win 下跑满虚拟网卡 100M 大约 14%。除了 cpu 占用高一些外,其他并没有明显差异,而且两者网络延迟差不多,并且都能跑满。


cpu 性能是瓶颈,但是感觉现在不重要。毕竟现在 cpu 性能普遍过剩。

而且 Windows 毕竟大多数是客户端,把性能负担加到用户,其实也是很普遍的行为了。比如著名的 electron 框架。
2615 次点击
所在节点    Go 编程语言
17 条回复
ysc3839
50 天前
14%是怎么看的?任务管理器“进程”那里是不准的,要看“详细信息”。
ebi5oowiiy1llo
50 天前
win 大多数场景性能都略差于 linux ,一方面是微内核,另一方面 linux 全球开发者帮它优化,windows 这时候还在写 w11 bug
Mithril
50 天前
没记错的话,Go 的 io.copy 在 Linux 上用的应该是 epoll ,单纯比较极限性能,Windows 上的 IOCP 应该和它差不多,甚至稍好一些。

如果是比较 Windows 和 Linux 的网络性能的话,最好是直接用系统原生的 API ,在物理网卡上跑。

但其实绝大多数情况你压根用不着这么极限的网络性能,有那时间和精力压榨这么点性能不如直接升级硬件。
DefoliationM
50 天前
win 的 io 性能本来就差。
wuruxu
49 天前
win10 讲性能,没有比 linux 好的,就是能跑的软件多
liuhan907
49 天前
Go 没怎么太关心在 Windows 上的性能。以及 IOCP 的模型和 epoll 的模型不兼容,Go 选择了照顾 Linux 环境而加重了 Windows 上的开销。论及纯粹的性能来说 IOCP 比 epoll 强,要到 io_uring 这个接口出现才算打平。
NightFlame
49 天前
@ysc3839 为什么不准
kkocdko
49 天前
@Mithril Go 的 io.Copy 在允许的情况下会 splice ,零拷贝。我不清楚楼主的场景是不是用上了。
seWindows
49 天前
@Mithril
@liuhan907

看了一下源代码,golang 会在每次 fd 操作时进行其余的句柄分离,以确保线程安全。看上去会从原始 Socket 从 IOCP 上解绑。

然后再 RawControl 与 dupSocket 调用获取新句柄,最后再把 newWindowsFile 包装成 *os.File 。
其他复杂的我没有深入追踪,可能和这个有关。每次分离应该都要进入内核态

https://github.com/golang/go/blob/master/src/net/fd_windows.go#L243

如果直接在同一个句柄上循环使用 WSARecv/WSASend 性能应该好得多 。但是对于现在 cpu 性能来说,应该是可以接受的,只会多占用一点 cpu
ysc3839
49 天前
@NightFlame 因为任务管理器会用实际的 CPU 使用率乘以 CPU 频率倍数。假如实际的使用率是 10%,CPU 基准频率是 2GHz ,实际频率是 4GHz ,那显示的使用率会是 20%。
NightFlame
49 天前
@ysc3839 #10 懂了,详细信息里的 CPU 列的数字怎么理解,大部分是 00 ,系统空闲进程是 90 ,这是 90%的意思吗
wwqgtxx
49 天前
@seWindows 正常的 Read 和 Write 调用根本不会走到那个 dup 的
如果你的说的是两个*net.TCPConn 直接 io.Copy 拷贝的速度,那单纯就是 Linux 下会调用 splice 而 windows 下没这项优化
seWindows
49 天前
@wwqgtxx 也许是这样,我只是粗略的看了一下。可能确实是 go 在 linux 下有比 Windows 的优化。
seWindows
49 天前
@ysc3839 感谢提醒,14%是在进程栏看的,“详细信息”确实只有一半。
wwqgtxx
49 天前
你所看到的所有分离 handle 操作本质上都和这个 issue 有关
https://github.com/golang/go/issues/19098
net 库中正常的 Read 和 Write 以及 ReadFrom/WriteTo 接口实际上都进入了 internal/poll 中使用 execIO 函数调用 iocp 完成,并不会封装成*os.File
opengg
49 天前
Windows 是二等公民
ysc3839
49 天前
@NightFlame 是的,详细信息里 CPU 那栏就是 CPU 使用率的百分比

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1150852

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX