卡内基-梅隆大学的编程竞赛

几年前,卡内基-梅隆大学(CMU)的计算机科学系有一个常规性的小型编程竞赛,参赛 对象是刚入学的研究生。竞赛的目的是让这些新的研究人员得到一些关于计算机科学系的直接经验,并让他们展示自己的强大潜力。CMU在计算机领域的研究历史 悠久,可以追溯到计算机的先驱时代,它在这个邻域所取得的成就可以说是非同凡响。所以,对于CMU举办的编程竞赛,其水准可想而知。
比赛的形式每年都不一样,其中有一年非常简单。参赛者必须读入一个文件(文件的内容是一些数值),并打印这些数值的平均数。只有两个规则:
1.       程序的运行速度要尽可能地快。
2.       程序必须用Pascal或C编写。
参数选手的程序集中之后由一名系工作人员分批上交。学生们可以自愿上交尽可能多的作品,这可以鼓励非确定性随机算法(就是猜测某些数据集的特征,利用猜测结果获得尽可能快的效率)的使用。决定性的规则是:运行时间最短的程序将获得优胜。
这些研究生们纷纷钻进各个角落,开始折腾各种各样的程序。他们中的绝大多数都准备了3到4个程序参加竞赛。
大多数人都猜想最大的赢家一定采用了代码优化措施,不管是显示地在代码中使用,或是通 过正确设置编译器选项隐式地使用。标准的代码优化技巧包括:消除循环、函数代码就地扩展(smecf注:使用inline内联)、公共子表达式消除、改进 寄存器分配、省略运行时对数组边界的检查、循环不变量代码移动(loop-invariant code motion)、操作符长度消减(把指数操作转变为乘法操作,把乘法操作转变为移位操作或加法操作等)等。
数据文件大约包含了10000个数值,假设读入和处理每个数需要1毫秒(当时的系统差不多就是这个速度),最快的程序也要用10秒左右。
 
实际结果非常令人吃惊。其中最快的一个程序,操作系统报告用时为-3秒。确实如此―― 优胜程序的运行时间是负数!第二快的程序大约用了几毫秒,而排名第三的作品恰好比预期的10秒稍微少一点。显然,获胜者在编程中作了弊,但他是怎样作弊的 呢?评委们在对优胜程序进行了仔细审查后,答案揭晓了。
这个运行时间为负的程序充分利用了操作系统。程序员知道进程控制块相对于堆栈底部的存 储位置,他用一个指针来访问进程控制块,并用一个非常大的值覆盖“CPU已使用时间”字段(这是一种对规则的臭名昭著的滥用,类似于阿根廷足球巨星马拉多 纳在1986年世界杯用上臂打入英格兰队一球的那只“上帝之手”)。操作系统未曾想到CPU时间会如此之大,因此错误地用二进制补码方案把这个非常大的数 解释为负数。
至于那个费时仅几毫秒的亚军程序得主同样狡猾,他用的方法有所不同。他使用的是竞争规 则而不是怪异的编码。他提交了两个不同的程序,其中一个读入数据,用正常的方法计算平均值,并将答案写入一个文件。第二个程序绝大部分时间都处于睡眠状 态,它每隔几秒醒来一次检查答案文件是否存在,如果已经存在,就打印其结果。第二个程序总共只占用了几毫秒的CPU时间。由于参赛者允许递交多件作品,所 以这个用时极少的程序就把他推上了亚军的位置。
季军作品所花的时间比预想的时间还要稍少一些。该程序的构思最为周详,程序员殚精竭 虑,用优化机器代码来解决问题,并把指令作为整型数组存储在程序中,由于在程序中覆盖堆栈上的返回地址是非常容易的(正如Bob Morris,Jr. 1988年在Internet蠕虫中所做的那样),所以程序可以跳转到这个整型数组并逐条执行这些指令。所记录的时间如实反映了这些指令解决问题的时间。
当这些策略被揭露后,轰动了全系。有些专家赞成对获胜者进行严厉批评;一群年轻教授则 相反,他们建议给他们额外的奖励以表彰他们的天才。最后,双方达成妥协。既没有颁奖,也未对他们进行惩罚,结果不了了之。令人悲哀的是,这个竞赛成了强烈 感情的牺牲品。从此以后,这个比赛再未举行。
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值