Monthly Archives: November 2005

网络民间公益活动

http://www.1kg.cn/
  多背一公斤项目:公益旅游活动。鼓励大家出行时多背一公斤文具或书籍,带给沿途的贫困学校或孩子。通过面对面的交流,激发孩子们的信心和想象力。

http://www.smilinglibrary.org/
  微笑图书馆项目: 组织大家把不用的旧书拿出来,寄送给贫困地区的孩子。

http://blog.cnblog.org/bloggercon/
  刚刚举办的首届网志年会,一个blogger拿一件T恤收集很多参加者的签名,然后进行拍卖,所得将捐给上面的两个项目。当然,拍卖采用Blog特有的方式,trackback。你会发现,已经有很多知名的blogger和创业者参与竟价了。

MEPG-4和AVS专利

  这两天网上CCTV数字频道用MEPG-2的新闻很显眼。AVS和MEPG-4/H.264是同一代信源标准,技术指标上远超过MEPG-2,都在试图取代后者成为市场主流。

  MEPG-4/H.264虽然比AVS早,但很多贡献很小的专利都想方设法挤了进去,使标准变得很复杂,收费过高。它不仅要求按软硬件收费,还要按时间流量计费,等于坐地收租,让运营商给他们打工。欧洲和日本都表示暂不接受MEPG-4/H.264。这给了AVS机会。

  而专利进入AVS标准前需要衡量是否必要;在技术指标相差不大时,优先使用过期或者免费专利。因此和MEPG-4/H.264比,AVS性能基本相同,复杂度和实现难度大大降低,费用基本就是象征性的,甚至比MEPG-2还低(1元人民币/2.5美元)。

  AVS未必是竞争的弱者:技术上只落后H.264半年;运作机制和专利费用上有优势……CCTV数字频道开播其实并非坏事,AVS的真正目标是这以后的巨大市场。

推荐书籍资料

  最近读过的几种有价值的技术书籍和资料。

  《Win32多线程程序设计》,英文名字:Multithreading Applications in Win32,侯捷翻译。虽然这书有些年头了,但内容和语言还是很出色。最近工作上参考了书里文件映射、共享内存和DLL线程安全的内容。

  《自己动手写操作系统》,难得作者这么年轻,更难得他这么年轻还这么踏实。读这本书很愉快,让我回忆起本科上操作系统课,阅读Linux内核,整理笔记的时候。

  《Google文件系统》,英文名:Google File System,很不错的资料(这里还有Google的其他技术论文)。GFS针对的应用的特点和生物信息领域很类似:海量的数据,动不动就上G的文件,还必须符合高速读取的性能底线;因为用廉价的PC集群取代昂贵的服务器,产生的对软件架构的特殊要求……得到不少启发:例如,不修改只添加、延迟删除的策略,就是一种简明的思路;再例如,把部件故障当作日常情况加以对待的设计原则,方案规划得很老到。

蛋白质数据索引

  阅读代码,画图,然后重构,单元测试……搞定了数据库部分。

  被数据结构的细节所纠缠。由于性能原因,无法使用通用数据库平台,只能自行开发一个数据服务。用各种酶在不同修饰条件下,对几十G 蛋白质数据进行酶切,得到肽离子,建立索引(即使最小的库,都有将近九千万条,而且每新增一种酶或修饰,数量还要翻倍),然后用文件映射方式,通过共享内存提供服务。

  其实我很欣赏系统最初的体系结构设计。但是由于1.5版deadline很紧张,老板施加了巨大的压力。为赶进度,工程师编程顾不上接口和重构,产生了大量的耦合和拷贝,弄得整个架构动弹不得。我接手后,只好回过头用几倍的时间阅读和重构代码,何苦呢?

  彻底重新设计了数据访问类,用一个纯虚父类做接口,隔开其他部分。每种具体实现方式作为一个子类,比如目前读取共享内存的代码。还打算把1.0版不通过索引的数据访问方式代码也移植过来,实现另外一个子类,提供给系统内存小于1.5G的用户。

  固定了接口,新版本就可以再实现其他数据访问方式,比如通过关系型数据库和Web Service提供数据服务。用关系型数据库的话,为保证效率满足Web应用,就必须用集群或网格了。这种情况一般都考虑Oracle,但涉及到老板的银子……听说Google采用MySQL,很希望知道他们的方案。

  今天跑通了单元测试案例,用的是马(Horse)的蛋白质库,不加任何修饰。Debug版访问所有肽链一遍,2.266秒。以前还真没对付过这种级别的海量数据。

BTW:早上去了趟所里,玩了玩曙光3000,酷。

本周收藏.2005.11.05

对象的多态技术

  C++的虚函数机制,是通过一个虚函数表存放函数指针实现的,一旦子类重载了虚函数,就替换掉表里的指针。COM的原理与此很类似,其中Interface可以看作纯虚类。C++是静态语言,函数表没有自描述性,调用代码完全是编译器由指针偏移量编译得到的硬编码。也就是说,虚函数表是定长的,即使是子类没有实现的函数,也需要父类的函数指针来占位。

  而Ruby等新一代动态语言,因为包含元数据,可以根据方法的名称进行查找。子类实现了几个虚函数,它的查找表就有多长,找不到再扔给父类继续查找。

  思路上,两者都是插入一个中间层,拦截外界对方法的调用,按照具体的类信息指定实际执行的代码。两者也有差别:动态语言因为涉及到字符串比较,查找效率相对差,而C++运行效率更高;但如果一个C++的父类提供成千上万的虚方法接口,即使子类只实现其中一小部分,也必须带着一个巨大的函数表,这显然造成了空间浪费。

  典型的,GUI架构如果采用虚函数机制,即使再小的对话框,例如‘确认取消’,甚至是只需要实现OnClick()的一个按钮类,由于是从Window类继承下来的,都必须带着一个存放几百甚至上千函数指针的函数表。

  为了对付这种情况,MFC没有使用虚函数,而定义了一大堆宏进行事件消息分发,虽然语法风格很丑陋,但保证了效率;而.net框架,发展出delegate机制,呵呵,兜了一圈,我们又回到纯C的回调函数风格了。

  参考资料很多:元数据、反射和delegate机制的资料都源于网上;C++和COM技术参考这两本:《Inside The C++ Object Model》和《COM原理与应用》。