跳到主要内容

听一次讲座有感

· 阅读需 7 分钟
Software Engineer

这周的周二到周五,有幸聆听了来自Portland State University计算机学院的XieFei教授的讲座,真是收获良多,颇受振奋啊。

这四天的讲座,每天都以一篇独立的博士论文为材料,介绍了软件工程方面的一些问题和解决办法。每天的讲解都以motivation开始,告诉我们为什么要解决这样一个问题,然后介绍解决的办法,最后得出结论以及效果如何,对未来应用的展望等。XieFei教授的讲解深入浅出,通俗易懂,而且互动性特别好,常常一针见血,给我的启发特别多。如果说我目前处于Level 2 的层次,那他就是在Level 4的层次在向我展示他们的成果,同时也会向我们介绍Level 6层次的人在做什么,为什么他们能领先我们那么多,为什么他们有那么高的价值。

先从这四篇论文说起吧。

1. Automate-Theoretic Approach to Hardware/Software Co-verification

简单说就是软硬件的协同验证。我们知道一个操作系统,除了内核kernel部分,有绝大部分都是各种各样的driver。windows xp有超过35000个driver,linux有70%都是driver,系统软件开发大多也是在做driver,真正动kernel的很少。用过win xp或者更早的操作系统的人,一定见过蓝屏死机,为啥呢?它就是在软硬件交互的时候(devices and device drivers)出的错,大概有52%的crash都是在软硬件交互的时候发生的。为了进行有效的软硬件协同认证,这里引入了formal specification和model checking的方法。但是在使用这些方法的时候,我们会面临三个问题:缺少形式化描述(通常使用英语来描述接口协议,但英语作为自然语言没有形式化定义),缺少一个统一正式的软硬件接口(软件是一个下推自动机,而硬件是有限自动机),缺少验证工具。这篇论文就针对这些问题,提出了一种合理且有效的解决方案,并且已经被应用到了工业界。 他们做的这个验证工具,在生产过程中,可以直接减掉一个环节的人工成本(雇佣一个工程师的价格是一年20万美金,而一个工具,显然要便宜的多),并且还能提高验证的正确率,这对老板来说可是一个不小的诱惑。而在IT界,有很多人就在做这样的工具,让工具来替代人的工作。工具可以一天24小时运转,工具不会有情绪,不会因为情感的波动而出错。这是一个好消息,也是一个坏消息。假如你不幸的被这种工具替代了,要么失业,要么学别的东西吧。所以,做对别人来说有用的工具,是非常有意义的一件事。(为什么图灵问题一直都不可解?图灵问题要是解决了,咱这做软件工程师的,可就都要失业喽。也正是因为如此,我们才有饭碗,我们才有工作去做)

2. Scalable Equivalence Checking for Behavioral Synthesis

在上个世纪的时候,硬件电路是手工画出来的,然后再拿去制作。后来引入了硬件描述语言HDL、VHDL,用它设计出来的硬件电路可以实现更高数量级的逻辑门的设计,这使得我们手边的笔记本电脑成为了现实。在从HDL到硬件电路的实现过程中(也叫逻辑综合),形式化验证方法起到了至关重要的作用,可以说这是它在工业界取得的一次巨大成就。随着工业界需求的不断升级,硬件电路的设计继续向上发展,出现了行为级,也就是软件级别的硬件电路设计。这样使得硬件电路的设计形成这样的模式,先由软件级别的语言来设计,然后生成硬件描述语言HDL(这个过程叫行为综合),然后再生成实际的硬件电路(即逻辑综合)。而这里就会出现一个问题,由高级语言设计硬件电路,通过编译器向HDL转换的过程中,是否等价?如果这里不等价的话,那么设计出来的错误的硬件电路在工厂里会以一夜几万块的数量生产出来。所以这个工作既重要又有必要。
文章里实现的方法是Clocked Control/Data Flow Graph,它使用我们都熟知的流程图,只不过在上面加上了时钟单元,这样就把行为综合和逻辑综合统一了起来。同时要检测由行为级生成的逻辑级的HDL语言是否一一对应(就像软件编译一样,中间会有很多步骤,每一步都会生成不同的中间代码),如果每一步的结果都进行检测,那么这部分工作会变得异常庞大而且耗时耗力,这会导致这种检测失去了它的意义。而使用一个简单的方法,我们就能让它运作起来,而且我们都学过这种方法,它就是数学归纳法。我不用判断g(0)和g(1),g(1)和g(2),一直到g(k-1)和g(k)是否等价,我们只用判断进入状态是等价的,结果是等价的,就能够保证,每一步的转换都是等价的。我们不用证明是否正确,我们只用证明转换前的版本和转换后的版本是等价的就可以。这个过程可以直接由符号执行去做,大大提高了检测的效率。

3. Post-silicon Functional Validation with Virtual Prototypes

一般公司在做一个产品的时候,一般会先做硬件,然后再开发软件,开发过程是顺序进行的。后来呢,在硬件开发和软件开发之间加入了虚拟机,在硬件开发到一定程度的时候,软件开发就可以在虚拟机上同时进行了,这样大大减少了开发时间,缩短了开发周期。但是如何保证这个虚拟机和硬件是一致的,也就是在虚拟机上测试通过的测试例,可以在真实的硬件上同样通过测试。那么这篇论文就提出了一种方法,concrete execution和symbolic execution结合的方式。可惜我对这些方法还都不太懂,所以我也没法具体介绍,论文里都有详细的阐述。
在教授介绍这篇论文的时候,他一再强调,我们做软件工程的人,很有必要去借鉴那些做系统的人的方法。比如他们仅仅用了六个函数就把硬件电路的模型给描述了出来,抽象的能力相当的强。最近我在看CSAPP(《Computer Systems A Programmer's Perspective》)的时候,书中也强调了“The use of abstractions is one of the most important concepts in computer science.”我想这一点,的确值得我们好好思考。

4. Automatic Fault Injection for Driver Robustness Testing

先来看一个driver调用kerner APIs的实际代码吧:

int *p = (int *)kmalloc(size,GFP_ATOMIC); 
p[10] = 3

问题很明显,即使是调用操作系统内核的API,也有可能会返回一个未知状态的指针。

int *p = (int *)kmalloc(size,GFP_ATOMIC); 
if(!p) goto error;
p[10] = 3;
// ......
error : error_handler();

这样怎么样?好一些了吧?其实,这只是把bug推到了后面而已。

这就是这篇论文要解决的问题。操作系统的driver大多都是第三方写的,driver在调用系统API的时候都会默认不会产生bug,可kernel的API也是人写的,谁能保证一定不会出bug呢?那么,出了问题怎么办?我们能否在测试的时候,就找到driver的这些错误,而不去更改kernel的代码?

这篇论文就针对这个问题提出了一种fault injection的方法来检测错误。它是将kernel的内核包装了一下,在其中加入了一些错误,尤其是调用跟内存有关的函数的时候。这样,当driver调用kernel APIs的时候,如果出现了错误而driver没有做错误检测,就能通过测试例发现这些bug。这种方法不需要去修改测试例,不需要修改kernel内核,就可以发现driver里的bug。测试的结果也显示,目前广泛使用的很多driver都被检测出了bug,这是一个相当有意义的事情。

这些论文在网上都可以搜到,别忘了强大的google,我个人的建议是能不用百度就不用百度,毕竟搜出来的东西,经常很难让人满意,容易浪费时间。说到这儿,教授提到说,在这个时代,信息是一个非常非常重要的资源,你获得了信息,你就获得了机会,如果你没有足够的信息,很多机会你都看不到。但也并不是所有信息对自己来说都是有用的,也有很多无用的垃圾信息,鉴别和保持清醒同样重要。

同时,教授还提到,保持一个open mind特别重要,如果有机会的话,多出去看看,多和人交流交流,不要把自己局限在一隅,不要给自己设限,自我定位不要太低,不要贱卖自己。这一点我也深有感受,自己对自己的认识和定位,决定了自己能达到的高度,如果连想都不敢想,那就永远都达不到。同时,和人交流也特别重要,我想这一点,每个和别人交流过的人,一定会体会到的,尤其是那些能给自己带来启发和营养的交流,绝对是“听君一席话,胜读十年书”。

此外,教授还说到一个关于学历和能力的关系,让我对它们的理解更深了一层。人为什么要上大学呢?教授的老板问了他一句话“Are you genius?”,如果是,那么大学没必要上;如果不是,那就去上,让自己去学习该有的能力。博士是干嘛呢?博士是发现问题(发现问题很重要),然后在发现问题的基础上,找到解决问题的办法。硕士是干嘛呢?硕士是在博士找到的解决办法上,在那个框架上,去具体的解决问题。学士干嘛呢?学士是把硕士的任务拿出来一个模块,解决这个模块里的问题,去实现这个模块。假如你具有了发现问题,解决问题的能力了,何必去花那个时间读博士呢?学历只是在找第一份工作的时候作为一个敲门砖,之后,一点用也没有。facebook等很多公司,直接雇佣美国的高中生,为什么?因为他们有这种能力,根本不需要更高的学历。反而,有很多博士,读出来却没有这种能力,那么他会跌的很惨。在企业里,为什么有人一年能拿200万,有人只能拿20万?因为他有那个能力去拿200万,能为企业带来效益,他就能解决你解决不了的问题。在软件界,优秀的程序员和很水的程序员的生产力可以差好几个数量级,你拿20个水程序员也比不过一个优秀的程序员,反而很水的程序员不是在贡献,而是在引入bug,然后修改自己引入的bug,这样一年还能拿20万的薪水,已经相当给面子了。所以,提升自己的能力,永远都是金钥匙。

对我自己来说,听完教授的这些讲座,收获和振奋是相当多的。我发现了自己不够专注的问题,不能专注认真的做好当下手头的事情,不能专注的去学习一个东西,而是既想学这,又想学那个,有时候又容易被别的事情分心。这对我最后一年的研究生生涯来说,至关重要。同时,我还意识到了motivation的重要性。不管做什么事情,一定要找到充分的理由去做这件事,这既是动力,也是它的意义所在。例如要做一个工具,结果并没有人需要用它,那么做这个工具这件事就完全没有意义。比如要解决一个问题,在工业界的确有能用到的地方,而且很需要它的解决方案,那么这件事就具备了充分的motivation。包括我在介绍这四篇论文的时候,也仅仅是描述了一下motivation,当motivation具备了之后,人自然就会想去了解具体内容是什么了。