Tag Archives: C++

不要技术自嗨

  去年看到一篇报道,讲一个创业团队先用C++开发一个大数据产品,然后又换成RUST花了半年重写一遍。理由仅仅是对语言的偏好。我回复了几句:“成熟的技术创业者选Java做主语言,不是不懂其他时髦语言,而是因为国内Java工程师的招聘和工资成本明显低于其他语言。技术领导者不能技术自嗨,要在更高层面思考,比如看看公司现金流,算算最坏情况能撑多久。做真正正确的决策。”

Do it yourself

  正在指导zk和wl在超龙一号超级计算机上安装配置pFind集群版。打算在960核情况下做一些加速比试验。和上次1024核试验很类似。很遗憾不能在龙芯CPU的节点上玩玩。

  哪吒系统在集群上全流程各环节并行。我一开始指望用点python有关的分布式并行框架,最后还是DIY。小马过河,有些地方挺困难(例如对虚拟机的管理和通讯),但总体来看,其实比想象简单。

  前几天提到,新版pFind核心使用了二级离子索引,但引入HBase不顺利。又发了些邮件开了些会,终于下定决心对查询部分推倒重来,抛开Hadoop等现有框架从头实现。方案确定,大家恍然大悟:原本就该这样做,花了半年证明HBase不行啊。

  上次BLOG最后写:“Java和C#逐渐不那么招人喜欢”,还链接了“Why do some people hate Java?"“Why we don’t hire .NET programmers”两篇文字,引来不少邮件和评论。俺的不少好友是Java和C#高手,并不想挑起语言口水战。那段文字也只是描述现象。具体从风格而言,这两种语言都是以“减少新手犯愚蠢错误”作为第一原则的,对初学者相当友好。不过也有点像乐高玩具,常规情况下简单易用,但面对更高的要求时(运行效率、开发效率等等方面),就不得不去了解大量水面以下的细节。相比起来,开源界的技术栈常常是哭着进去笑着出来。

Dennis Ritchie去世,还有一段个人记忆

  首先,C语言之父Dennis Ritchie去世,默哀。大家可以回顾一下这篇2000年的新闻稿,记者专访了C、C++和Java三种语言的创始人。C++11标准终于发布了,ISO C11新版也会马上发布。C标准委员会和C++标准委员会关系很好,有很多成员在两边兼任,所以相互协同越来越好。只可惜,自从SUN被收购,眼看着Java要被Oracle生生折腾死了。

  OK,技术写完了。

  前两天收到好朋友的消息,说我的BLOG上长篇大论的技术review越来越多,鲜活的个人体验越来越少。朋友提醒我,不要被点击量和搜索排名绑架,不要忘记那些关注你个人的好朋友们。说得对,BLOG之所以不同于其他媒体,在于其背后是个活人,有喜怒哀乐和碎碎念。订阅者若是只关心宏大严肃的话题,就去看《南方周末》了。

  下面是一段无关技术的记忆,分享给关心我的好友,也分享给上岁数以后的自己。

  战争,窗户外面轰炸机正在扔炸弹,火红的爆炸和灰滚滚的尘土,小区里的楼开始摇晃歪倒,多米诺骨牌,一栋、两栋……终于轮到我这一栋楼了,卧倒,地板逐渐倾斜,周围充满了邻居们的叫喊……

  女儿的抽泣把我从梦里拽出来。睁开眼睛,小婴儿正在吭叽,努力试图侧过身子,离妈妈近一点。妻子还在睡梦里,一只手揽着孩子,胳膊肘顶着我的肩膀,哦,是怕我梦里翻身会不小心压到孩子。

  女儿不懈挣扎,用脚踢被子,发出更大声音的抗议……妻子很快醒了,侧过身给孩子喂奶。孩子急躁地叫起来,妈妈温柔而疲惫地安慰,然后就是小家伙咕噜咕噜吃奶的声音。

  给女儿盖上被子,问“换尿布吗?”,妻子说“不用,你睡吧”。

  卫生间里的冷光夜灯透过来,描出母女两个的轮廓来,像大理石雕塑。翻身,裹好被子,深呼吸,安详温暖的气氛,刚才噩梦里的紧张纠结已经很远很淡了。困倦,接着睡……

  补:教主说,闭上眼,且听风吟;这一刻,世界与我无关。

《寻羊冒险记》和C++0x

  这两天和瓶子哥进行双人编程,对pFind内核进行新一轮的重构迭代。好久没有经历这么高强度的编程了。今晚10点回来的地铁里,脑袋都木了,发呆,差点儿坐过站。

  今天的todo list里规定必须写blog,所以就打开Firefox,登录上来开始敲字。但说实在的,累,脑袋里没找到特别鲜明的主题,罗列点杂七杂八的流水帐。不好意思:)

  前天到清华参加AKA的linux kernel会议路上,顺便到光合作用买了村上春树的《寻羊冒险记》卡特琳娜·哈克的《空房间》。非常喜欢《寻羊冒险记》,觉得比《挪威的森林》更好玩。

    

  Herb Sutter刚刚在他的BLOG上给出了C++0x的最新进展。像6月Sophia Antipolis会议预计的一样,C++委员会在San Francisco会议上投票通过了草案,正式进入ISO标准公示阶段,点击这里下载C++0x草案文本。另外,Herb Sutter结束了长达10年的C++委员会的主席任期,由P. J. Plauger接任。

标准和政治

  还没搜索到旧金山会议和C++0x草案的消息,看样子是拖延了。索性沉下去挖掘点可写的历史遗迹。

  以前提过,没有ABI标准是C++语言最大缺憾之一。Google一番,发现Pete Becker于2003年提交过有关的N1496号提案。提案建议添加shared关键字,用来申明动态链接库对外共享的变量、函数、类和模板。不过该提案最终未被纳入C++0x标准。

  从技术角度,它不失为一个不错的解决方案。麻烦在于政治原因。“委员会设计”就是这个样子,张雨生的歌里唱:“看你服气不服气,51比49”。 

  说起厂商政治问题,Bjarne Stroustrup有个著名的观点:“通过技术突破来解决政治问题”。也就是说,如果厂商的工业级产品各占山头互不兼容,C++标准委员不打算插进去,搞出个姥姥不疼舅舅不爱的another来。除非它在技术上拥有足够的创新优势,现有解决方案无法比拟。“STL的成功源于技术突破。它可不仅仅是另一个容器库,因此不需要和许多市场上已有的商业容器库(其中几个还很不错)直接竞争。”

  由此就知道C++为何迟迟没有GUI标准了,Bjarne Stroustrup说:

  “我怀疑其政治上的可行性……很多大公司在其专有GUI库上都有重大商业利益。即使标准委员会提供一个替代品,现有GUI库也不会轻易退出市场,厂商的抵制会导致用户忽略新标准。许多ISO标准正是因为无人理会而变成一纸空文,C++标准可不想成为其中之一。”

  老大的意思很明确:同志们就不要盼了。假设哪天C++标准里真加入GUI,一定源于某种革命性的技术突破,能把现有GUI解决方案打得满地找牙。这种救世英雄横空出世,是需要点儿运气的。

里程碑

  这两天算是很多公私事不大不小的里程碑。

  工作上,昨晚pFind引擎终于跑完一个磷酸化数据集,时间只有Mascot的一半,更大大快于SEQUEST,鉴定精度也不错。感觉有些累。晚上出去吃火锅,回来喝了点啤酒。

  业界大事方面,像之前说的,Python 3.0和C++0X目前也是关键时刻。Python 3.0刚发布了第一个release candidates,而WG21 Fall 2008 meeting按计划是今天结束

  至于一直想要的书,Beautiful Code中文版9月22日全国发售,希望上海能买到。

  想回北京:想玩WII,想吃黑竹笋火锅,想去乔波滑雪。

C++0x、Python3.0、《The Beatles 1》和《再袭面包店》

  有段时间没有写技术了,接下来打算收拾心情写点专业的内容。

  9月份将有不少大事,C++语言要推出0x新版Python语言要出3.0,跟进中:Google将在San Francisco举办WG21,C++委员会漫长的投票终于要结束了,计划9月20日提交C++0x标准稿;Python 3.0已发布Beta3,并确定这是最后一个Beta包,将于10月1日final release。下面是九月份的TIOBE排行榜:Java和C/C++依旧两强对峙,占据工业级通用语言的领先地位;Python同比去年又高了将近2%,有望成为第二集团的领头羊;微软放弃VB,众多VBer按惯性转移到了C#。

  

  最近在听甲壳虫乐队的专辑《The Beatles 1》。第一次听甲壳虫乐队是高中时代(看比尔盖茨的《未来之路》,书里提到他少年时代每周末收听流行歌曲节目)。俺最喜欢的还是那首《Hey Jude》。以前认识一个心理学专业的朋友,单单根据这个,就猜我是单亲家庭,少年时代经历过父母离婚,真神。

  昨天上火车前,在光合作用买到村上春树的短篇小说集《再袭击面包店》,看完了同名的第一篇小说,好玩,俺也想和特立独行的老婆一起袭击麦当劳,抢走30个汉堡

关于异常机制和编程style

  首先放张照片,程序员责任重大,除了正常逻辑部分,还必须在异常发生时周到地帮助无辜的用户。

  八卦点题外话,是在Google著名华裔程序员王忻(Niniane Wang)BLOG上看到这张照片的。她刚刚发布了引起轰动的Google Lively。新闻里说Lively是工程师20%时间的业余开发成果。考虑到她的年龄只比我大一个月,实在让人绝望呀。 你去看看linux操作系统内核的历代版本负责人,从Linus本人上大学期间发布0.02开始……2.2版、2.4版、2.6版的总维护人都不到26岁 就掌管内核代码主干版本。像大一还没上完就写出抢占式调度补丁的Robert Love(很多人都说他有可能是下一版2.8内核的代码总维护人)这种,都只能算稍微年轻一点的。到了30岁,程序员的黄金时代就过去了,只好靠留大胡子唬人了(Guido van Rossum进了Google以后,真的留起胡子来了,咣当)。

  回过头来说正经的,相对C,C++最有价值的改进就是exception了。这半年来pFind的重构,一 个水面以下的最大变化,就是把以前return false和GetLastError()风格,用throw和try代替。当然这需要大量的体力活,刚开始遇到不少疑惑。但后来所有人都发现这是偷懒的 好方法。一个例子是,老版代码发现一个bug,异常位置和崩溃位置差很远,就是因为前者的return false链条断掉了:出错的函数上面套了11层调用者,有一层没判断返回值。纯C语言的灵活性和直观性的代价是,程序员必须是铁人,有能力妥善处理一切细节。

  有了完整的exception处理机制,一旦出现崩溃,pFind2.1就立刻把运行现场所有的信息都记录 下来,这样有利于调试,特别是无代码,或BUG重现需要很长时间的情况。这两种情况俺们都要面对:pFind将在网上开放下载,散播到世界各地的生物学实 验室;蛋白质鉴定是计算密集型应用,有时候release版运行一整夜才跑到出问题的地方,指望debug版加断点调试是很低效的。

  至于现场信息的携带,没有复杂的异常类继承体系,仅仅依靠字符串。组里聪明的年轻人设计了一个异常信息格式化的类,可以很方便地在每个堆栈展开catch的地方追加新的现场内容。这样一层一层加上去,形成类似JAVA的异常报表。

  常见的疑问是exception有性能问题。可能不同应用要求不一样。经过实际测试,pFind的性能瓶颈不在这方面。似乎新版GCC编译器对此做了优化。

  说到C和C++的比较,很多人可能要提到云风Linus,以及之前关于C++的大论战。 在很多技术问题上赞同云风的观点,甚至有点崇拜。但一直老老实实用C++,没有追随他叛出山门,回到C语言。原因很简单,C++对这个项目更合 适:pFind是一个有二、三十个模块,几十万行代码,十几个人合作,历时五年的项目;它很看重速度和性能,但优化的大头,都在流程和算法方面,除了最关 键的“热点”以外,其他部分不必也不能牺牲代码的可维护性;而开发人员水平又参差不齐,很多人无法达到用纯C开发大型系统必须的素质要求(像前面提到的 bug,传统C风格异常机制下,出错后需要11个函数依次return false,穿越4个不同作者不同时期的代码,只1处懒惰就抵销了其他所有严谨。俺的团队很难达到这种程度的严丝合缝,也没必要付出这么高的开发成本)。 这就注定了C++是唯一的可选项。一直在关注其他各种语言,比如D语言,但现实来说只有C++符合条件。

  Andrei Alexandrescu对这个问题的看法很中肯: 像Linus这样的牛人,他很清楚自己在干什么,开发操作系统内核,合作者都是天才,所以他就真的不需要C++。云风的deepcold引擎很类似,对性 能,尤其是一小段时间内(例如0.2秒内)的数据吞吐反馈能力有严格要求,网易又有一帮真正的geek组成的技术团队。

  C++最大的陷阱就是程序员——尤其是新手——过分追求奇巧淫技的风气。所以在pFind内大面积推广的都 是最朴实的,甚至有点土气的style。例如,继承只在纯虚类接口一种地方使用(具体说就是工厂方法模式);而功能复用都以内嵌对象来实现,不允许继 承。(整天喊口号:“接口上移,功能外抽”)。对神奇的泛型基本回避,限制写模板,熟练使用STL就行了。尽管Andrei Alexandrescu的《Modern C++ Design》里的内容很酷(软件开发2.0大会还专门买了一本新的,请他本人签名)。但pFind团队没有能力把握这种style。

  C++是一种多style语言,架构师需要做的,就是明智地裁剪符合需要的子集。约束团队抵御诱惑,不拿手头的任务当学习新技术的小白鼠。

  BTW1:Python和C++社区的关系很好,很多老牌C++程序员同时也是Python著名玩家,例如豆瓣的阿北。C++标准委员会那帮人甚至在boost里加上了连通Python的内容,还公开说Python是C++的最佳伴侣。Python和C++差异很大,比如是动态语言,比如“所事情只需要一种方法”的设计哲学,这种不同恰恰造成了互补。

  BTW2:最后推荐Google刚刚公布的C++代码规范。哈欠,睡觉去了。

C++0x能不能在09年发布?

  搞定了pFind里程碑,放松下来踅摸踅摸天下大势。有段时间没跟进C++0x的进展,今天上网搜索了一下,整理出来。

  C++委员会6月份刚刚在法国的Sophia Antipolis举行了会议(WG21)。会议的最大成果是确定了C++0x发布时间,漫长的投票表决过程总算接近结束。今年9月将提交委员会草案,以便公众审阅和反馈,进入ISO程序。Herb Sutter强调,9月的委员会草案就是”feature-complete C++0x“,以后的修改仅仅是bug修正和澄清。希望C++0x的这个“x”是9,而不升到A。

  技术细节上,这次会议有两个最主要的features通过投票:

  首先是传说中的Initializer lists提案(N2672  N2679),以后可以用更直观的方式初始化STL容器了:

     vector<string> v = {“xyzzy”, “plugh”,  “abracadabra” };
     map<string,string> phonebook =
          { { “Bjarne Stroustrup (cell)”, “+1 (212) 555-1212″ },
             { “Tom Petty (home)”, “+1 (858) 555-9734″ },
             { “Amy Winehouse (agent)”, “+44 99 74855424″ } };

  第二项是thread_local( N2659 )。经过近一年来的几次投票,并行机制的内存模型、原子操作和线程包装的多项提案都已经通过投票,这大概是C++0x最重要的变化。

  其实每次都会投票通过几十个features,只不过大多数没引起注意,比如我无意瞅到了一项07年获得通过的提案,是Herb Sutter代表微软提交的空指针关键字nullptr (N2431) ,这就可以用nullptr替换VC++下的NULL宏,免得每次往gcc下移植都得手工加入。

  这次唯一留的尾巴,大名鼎鼎的conceptsN2081),仍在等待“check in”。按照Herb Sutter的说法,这方面争议基本解决。9月份的San Francisc会议只要就此投票,即可扫清最后障碍,发布标准草案。 

  以上信息都依据网上来源:Bjarne Stroustrup的C++0x概述报告slices,Google的Lawrence Crowl对线程模型的报告slices, MS的Herb Sutter的BLOG、CodeGear的Alisdair Meredith的BLOG。他们都是委员会成员。另外我还找到一个旁听会议的Java程序员的BLOG,由于视角不同,难免有不少比较,比如C++委员会与JCP的异同。当然,你也可以参考正式、全面但枯燥的会议记录

关于C++的ABI

  如果要给最头疼的C++特性投 票,我会选ABI兼容:C++标准没有明确跨编译器的二进制兼容,于是各个编译器的实现都不同。用VC在Extension Dll里实现一个类,到了gcc代码里就不能直接调用。这带来了很多麻烦,尤其在有移植和平台兼容需求的大项目里。最近我的项目进行下一步规划,就为培训新手挠头。

  更糟的是,这还导致其他编程语言不能简明地“胶合”C++:大多数编程语言的编译器或解析器都是以C/C++实现的。按理说来,在这些语言中调用C++的类应该是很容易实现的天然属性。但是正由于ABI不兼容,这些语言要支持C++二进制调用就必须先选择编译器:到底是支持VC还是 gcc?因此很多语言避开C++,以纯C形式的动态链接库(Windows下就是Regular Dll)作为对外胶合的二进制接口。这进一步影响到不少混合语言项目选用C而非C++与动态语言进行高低搭配。

  作为实现“底层硬核”的系统级语言,C++的调用接口这种基础机制不理想,负面影响有些大。

  当然也有不少对应的解决方案。最有名的是COM,它利用类似虚函数表的方法,建立语言无关的接口兼容模型,微软把Windows系统的几乎所有的模块接口都变成了COM,比如ActiveX和DirectX。还有其他一些常用方案,像SWIG。普通一点的方法是用C语言接口做桥接。

  前几天刘未鹏征求中国程序员给B.S.的问题,俺问ABI标准啥时候有指望。据说问题的关键不是技术,而是C++标准委员会各大厂商间的政治原因。

  BTW:最近玩D语言,本来就是一帮C++高手另立山头搞出来的,自然是针对后者的软肋作改进,目前看起来的确很美好。不过二十年前C++刚从C里面蜕变出来时,看起来也很美。路漫漫其修远兮。