系统与基础设施pdl.cmu.edu
用 30 条指令实现 TCP(1993)
TCP in 30 instructions (1993)
2010 — 2015,它一次次回到首页
黑点是上首页(≥ 50 分)的那次投稿,空心点是没冲上去的投稿,点越大分数越高。
导读
这是网络传奇人物 Van Jacobson 在 1993 年邮件列表中的著名帖子:他展示了 TCP 接收端处理在常见快速路径上只需约 30 条指令即可完成,并犀利批评了当时 BSD 实现中的编译器缺陷、mbuf 链低效等问题。需要说明的是,这只是 TCP 分段接收处理的一部分,并非完整的 TCP 逻辑。
为什么经久不衰:它以极简的方式揭示了高性能网络栈的核心思想——针对常见路径做极致优化,这一思路至今仍影响着 Linux 等现代 TCP 实现。
HN 评论精选
提醒读者:30 条指令只是 TCP 接收的快速路径,并非完整 TCP 实现。
这是一篇非常著名的帖子,Van Jacobson 是典型的网络系统编程大牛。不过要注意背景:这里讲的只是 TCP 每个分段的接收处理部分,描述的是分段可以走的一条简单快速路径,而不是全部 TCP 逻辑!
tptacek查看英文原文
This is a very famous post, and Van Jacobsen is the archetypical networking systems programming bad-ass. Important context here though: this is just the per-segment receive processing piece of TCP; it's describing a very simple fast path that segments can take, but not all the TCP logic!
详细拆解了'30 条指令'的适用范围和前提,指出这是对常见路径的激进优化。
这 30 条指令并不包括 IP 上调、TCP demuxer 等步骤(IP 处理约 25 条指令,demuxer 约 10 条)。另外注意'几乎总是'这个词:if 的第一个条件同时检查了窗口、无 TCP 选项、ACK 标志位、连接状态四件事,第二个条件检查包是否按序。结果是正常接收路径执行 16 行 C 代码,在 SPARC 上变成 33 条指令。这种做法重度优化了常见路径,而牺牲了非常见路径的性能。IBM 的 AIX 当年也做过类似的事,把几乎整个 TCP 放进硬件中断处理里,快得离谱。
mcguire查看英文原文
The 30 instructions don't include "In the case of TCP, the upcalls almost always go two levels: IP finds the datagram is for this host & it upcalls a TCP demuxer which hashes the ports + SYN to find a PCB, lays the packet on the tail of the PCB's queue and wakes up any process sleeping on the PCB. The IP processing is about 25 instructions & the demuxer is about 10." Further, note the "almost always"; it's true, but it's not "always". Also, there's "So, the first term of the 'if' checks four different things simultaneously: - that the window is what we expect - that there are no tcp options - that the packet has ACK set & doesn't have SYN, FIN, RST or URG set - that the connection is in the right state and the 2nd term of the if checks that the packet is in sequence..." The result is that "On the normal receive data path we execute 16 lines of C which turn into 33 instructions on a sparc (it would be 30 if I could trick gcc into generating double word loads for the header & my carefully aligned pcb fields)." Note the phrase, "normal receive data path". Again, "almost always" is not necessarily "always". This heavily optimizes the common path while penalizing the uncommon path. IBM's AIX also did something similar, back when I knew anything about it; it did almost all of TCP in the hardware interrupt handler, making the same assumptions of windows, options, flags, connections, and sequence numbers. It was ridiculously fast. On the other hand, the non-fast-path cases have to be handled somewhere and are considerably more than 16 lines of C. Further, I'm not sure all of the assumptions are valid any longer. One assumption in AIX was that the incoming packet was the next segment of the same connection as the previous packet. That was true then, but may not be true now given that servers are handling more connections than back in 1993. YMMV. Offer not valid in all 50 states. Don't shoot the messenger. Yes, we have no bananas.
赞赏 Van Jacobson 犀利直率的写作风格。
我喜欢这种观点鲜明的写作风格。可惜我对这方面了解不够,无法完全体会文中关于'编译器脑残'、'mbuf 链愚蠢设计'和'netipl 软件中断扯淡'这些评论的妙处。
grannyg00se查看英文原文
I love the opinionated writing style. I wish I knew more about this so I could relate to the comments about the "compiler braindamage", "mbuf chain stupidity", and "netipl software interrupt bs".
提供了更易读的 PDF 版本,并指出它与 Linux 内核 TCP 接收代码的关联。
有一个更好读的 PDF 版本:http://people.cs.clemson.edu/~westall/853/notes/vanjtcp.pdf。我是在阅读 Linux 内核接收路径代码时偶然发现这篇文章的。
majke查看英文原文
Previous: https://news.ycombinator.com/item?id=6971935 I was looking for a good link, this is a bit nicer to read but in pdf: http://people.cs.clemson.edu/~westall/853/notes/vanjtcp.pdf Stumbled upon when reading the linux receive path: https://github.com/torvalds/linux/blob/dd5cdb48edfd34401799056a9acf61078d773f90/net/ipv4/tcp_input.c#L5193
历次讨论
同类还值得读
TTY 揭秘(2008)
The TTY demystified (2008)
经典文章深入剖析了 Unix/Linux 中 TTY 子系统的工作原理,包括线路规程、终端驱动、信号与控制字符等机制。
系统与基础设施上首页 11 次 · 2009–2025linusakesson.net编辑精选为什么 GNU grep 这么快
Why GNU grep is Fast
FreeBSD 邮件列表上一篇广为流传的帖子,解释 GNU grep 为什么快:核心在于 Boyer-Moore 字符串搜索算法配合精心优化的内部循环和 I/O,让程序在搜索时“…
系统与基础设施上首页 9 次 · 2010–2022lists.freebsd.orgXplain:为普通人讲解 X11
Xplain – Explaining X11 for the rest of us
《Xplain》是作者(HN 用户 Jasper_)写的一系列 X11 长文,用他在浏览器中重建的 X11 绘图模型做交互演示,讲解 X11 的绘图模型与窗口系统设计。
系统与基础设施上首页 6 次 · 2013–2020magcius.github.io编辑精选旋风教程:为 Linux 创建极小 ELF 可执行文件(1999)
A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux (1999)
breadbox 写于 1999 年的经典教程,主题是如何为 Linux 手工构造并裁剪出体积极小的 ELF 可执行文件。
系统与基础设施上首页 6 次 · 2007–2025muppetlabs.comPostgreSQL 内部原理
The internals of PostgreSQL
《The Internals of PostgreSQL》是一本免费在线书籍,系统讲解 PostgreSQL 的内部实现,包括查询处理、并发控制、WAL、缓冲区管理等核心机制。
系统与基础设施上首页 5 次 · 2017–2025interdb.jp编辑精选