读 ACE 现在的代码,一股学生气扑面而来,感觉像在读实习生写的代码。抛开编码风格不谈,这里举三个“硬伤”: sleep < 2ms 在某些早期的 Linux 内核上,如果 select/poll 的等待时间小于 2ms,内核会采用 busy-waiting。这是极大的 CPU 资源浪费,而 ACE 似乎没有考虑避免这一点。 Linux TCP self-connection Linux 的 TCP 实现有一个特殊“行为”,在某些特殊情况下会发起自连接。而 Linux 网络协议栈的维护者认为这是一个 feature,不是 bug,拒绝修复。通常网络应用程序不希望出现这种情况,我见过的好的网络库会有意识地检查并断开这种连接,然而 ACE 漠然视之。 timeval on 64-bit ACE_Time_Value 类直接以 struct timeval 为成员变量,保存从 Epoch 开始的微秒数。这在 32-bit 下没问题,对象大小是 8 字节。到了 LP64 模式的 64-bit 平台,比如 Linux,对象大小变为 16 字节,这么做就不够好了。我们可以直接用 int64_t 来保存这个以微秒为单位的时间,64-bit 整数能存下上下 30 万年,足够用了。减小对象大小并不是为了节约几个字节的内存,而是方便函数参数传递。在 x86-64 上,这种 8 字节的结构体可以用 64-bit 寄存器直接传参,也就是说 pass by value 会比 pass by reference 更快。对于一般的应用程序而言,要不要这么做值得商榷。对于底层的 C++ 网络库,不加区分地使用 pass by reference 会让人怀疑作者知其然不知其所以然。 对于以上几点情况,我怀疑 ACE 根本没用在 Linux 大规模生产环境下使用过,我只能期望它在别的平台表现好一些了。ACE 的作者们似乎更注重验证新想法,然后发论文,而不是把它放到工业环境中反复锤炼,打造为靠得住的产品。(类似 Minix 与 Linux 的关系。) 4. 移植性很好,支持我知道的和不知道的很多平台 ACE 的意义在于让我们明白了C++代码可以做到可移植,并展示了这么做会付出多么巨大的代价。不细说了,读过 ACE 代码的人都明白。 从代码质量上看,ACE 做到了能在这些平台上运行,但似乎没有在哪个平台占据主导地位。有没有哪个平台的网络编程首选 ACE? 出现这一状况的原因是,跨平台和高性能是矛盾的。跨平台意味着要抽象出多个平台的共性,以最 general 的方式编写上层代码。而高性能则要求充分发挥平台的特性,剑走偏锋,用尽平台能提供的一切加速手段,哪怕与其他平台不兼容。网络编程对此尤为敏感。 我不知道 ACE 的性能如何,因为在各项性能评测榜上基本看不到它的名字(c10k 里就没有 ACE 的身影)。另外,Buffer class 的好坏直接反应了网络库对性能的追求,ACE 提供了比 std::deque<uint8_t> 更好的输入输出 Buffer 吗?(我不是说 deque 有多好,它基本是 fail-safe 的选择而已。) 5. ACE 过于复杂,甚至比它试图封装的对象更复杂。 (这里的代码行数均为 wc 命令的粗略估计。) ACE 5.7 自身(不含 TAO 和 CIAO)有 30 万行 C++ 代码(Douglas 自己给出的数据是 25 万行,可能指的是略早的版本),这是一个什么概念呢?我们来看 TCP/IP 协议栈本身的实现有多少行:(均不含 IPv6) TCPv2 列出的 BSD4.4-Lite 完整 TCP/IP 协议栈代码有 15,000 行,其中 4,500 行 TCP 协议,800 行 UDP 协议,2,500 行 IP 协议 Linux 1.2.13 完整的 TCP/IP 协议栈有 2 万多行 (net/inet) Linux 2.6.32.9 的 TCP/IP 协议栈有 6 万多行 (net/ipv4) FreeBSD 8.0 的 TCP/IP 协议栈有 5 万多行 (sys/netinet, 不含 sctp) 换句话说,ACE 用 30 万行 C++ 代码“封装”了不到 10 万行 C 代码(且不论 C++ 代码的信息密度比 C 大),这是不是头重脚轻呢?我理解的“封装”是把复杂的东西变简单,但 ACE 好像走向了另一个方向,把不那么复杂的东西变复杂了。 这个对比数字可能不太准确,因为 ACE 还封装了很多其他东西,请看。http://www.dre.vanderbilt.edu/Do ... l/ace/inherits.html 和 http://www.dre.vanderbilt.edu/Do ... /ace/hierarchy.html 以下两张类的继承关系图片请在新窗口打开: Douglas 说 ACE 包含了 40 人年的工作量,对此我毫不怀疑。但是,网络编程真的需要这么复杂吗?TCP/IP 协议栈的实现也没这么多工作量嘛。或许只有 CORBA 这样的应用才会用到这么复杂的东西?那么为什么 ICE 在重新实现 CORBA 的时候没有基于 ACE 呢?是不是因为 ACE 架子拉得大,底子并不牢? |
转载于:https://my.oschina.net/zhangjie830621/blog/188219