主要观点:
- 程序使用“vmsplice”系统调用可更快通过管道移动数据,作者研究为何非“vmsplice”时 Linux 管道比预期慢及能否改进。
- 理想情况下可达到 167GB/s 写入数据速度,实际写入管道仅 17GB/s,慢 10 倍,原因是需花费大量时间获取锁且无法高效使用向量指令。
- “vmsplice”可通过将整个缓冲区从用户空间移动到内核而不复制来减轻使用管道的成本,能达到 210GB/s 以上,但实际应用中需填充新数据。
关键信息和重要细节:
- 作者写快速摩尔斯电码程序需通过管道移动数据,以 Code Golf StackExchange 的 Fizz Buzz 吞吐量竞赛为参考,第一组未使用“vmsplice”达每秒几吉字节,第二组使用“vmsplice”达每秒 15.5 至 208.3 吉字节。
- 理想情况下通过无系统调用的程序可在作者系统上达到 167GB/s,使用 AVX - 512 时在 L1 缓存写入速度与此一致,禁用 AVX - 512 等仍为 167GB/s,说明只要使用向量化就能达到该速度。
- 实际写入管道时,大部分时间在“__GI___libc_write”系统调用及“pipe_write”函数中,36%时间在“__alloc_pages”分配新内存页,25%在“__mutex_lock.constprop.0”锁管道,20%在“copy_user_enhanced_fast_string”复制数据,该函数未使用向量指令导致速度慢,作者改编 Rust 程序使用“REP MOVS”后吞吐量为 80GB/s。
- “vmsplice”工作原理及使用“./write”程序测试,发现使用“vmsplice”时花费时间在“__mutex_lock.constprop.0”等函数,避免了“write”系统调用的昂贵部分,且缓冲区大小对系统调用次数和吞吐量有影响。
- 总结为写管道比写原始内存慢 10 倍,“splice”和“vmsplice”可避免锁成本和 SIMD 上下文保存恢复成本,绕过保守的内核代码,但实际读取数据仍有惩罚达不到 167GB/s。
备注:文中多处有勘误说明,如错误指出停止的指令等情况。所有基准测试在作者个人台式电脑上进行,包括特定硬件和操作系统配置等。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。