巴别塔上的雇工


放弃《龙虎门》
10月 31, 2006, 11:23 上午
Filed under: 八卦杂谈

好的故事,人物都是有生命的,可能做意料之外的事情,但是都在情理之中。《龙虎门》漫画中的情节,过于突出打斗,除了打还是打,打斗的部分太多,没有留下多少空间展现人物性格变化,所以说,情节不好,我无法忍受了,丢到垃圾桶里去吧。



Math
10月 30, 2006, 1:13 下午
Filed under: 工作心情

今天Steve从总部来北京,给我们培训Classifier,有很多数学相关得东西,还好我事先在wikipedia上找了一些相关主题,及时补了一下课,这才听得懂个七七八八。刚进大学得时候,都说干这行数学一定要好,但是工作了之后觉得觉得数学这东西搞研究还有点用,但是如果是做工程师,就没有数学用武之地了。现在觉得,如果只是做programmer,数学用处真不是很大,但是在MS不光是programming,还要想出solution,只恨当初数学没学好,现在经常需要复习一下数学。



Stack-based vs Register-based
10月 28, 2006, 3:55 下午
Filed under: 技术体会

要真正用好一项技术,就一定要理解技术表面之下的东西。使用C#,不能光知道怎么写基本语句,记住常用API就完事了,要知道这背后的东西,能够看懂编译之后产生的MSIL是必要的。

今天学习了一下MSIL,还是有点惊诧,本以为和x86的汇编代码差不多,但是发现自己一开始什么也看不懂,而且工作方式和x86也很不一样。x86汇编代码中,是对一个一个寄存器进行操作,而IL里面没有寄存器这个概念,所有被操作的东西都先push到栈上,然后调用一个指令,然后再pop取得结果。

x86的这种方式叫register-based,MSIL这种方式叫stack-based。

理论上,stack-based的方式比起register-based的方式有很多优点。

一般指令中每个元素都至少占一个byte,对于register-based,一个求和指令,只能写成类似这样的

     ADD R1, R2, R3
    ADD R1, R2

第一种方式,ADD是opcode,R1和R2是输入,加的结果放在R3里面,如果和第二种方式一样,R1和R2只和就放在一个缺省的寄存器或者R1和R2之中一个,总之至少需要3个byte来描述一条加动作的指令。而对于stack-based,被加的数在栈上,输出也要放在栈上,一个byte的指令就够了,当然把输入放在栈上还需要别的指令,但是对于一串连续的指令流,往往前一条指令的输出(放在栈上),就是后一条指令的输入,所以整体而言,stack-based的代码会比register-based小。

同样的道理,stack-based中调用函数也方便得多,不需要像register-based一样把register上得东西先push到栈上(当然根据convention,有的参数和返回值也可以直接放在register里面)。

运行环境(进程或线程)的切换,stack-based也方便得多,和当前运行环境状态相关的变量都在栈上,只需要让指令到另外一个栈上去跑就好了,等切换回来一切和从前一样。对于register-based,不得不在切换之前把register一一存下来,切换回来再一一恢复,如果reigster比较多,开销就比较大。

既然stack-based这么牛,那为什么我们常见的处理器都不是stack-based,而傻傻的用register-based呢?这是因为regiser-based纵有千般不是,它的性能高,它适应市场。我们知道同样的容量,硬盘比内存便宜,内存比缓存便宜,缓存比寄存器便宜,构成了金字塔形状的层层cache关系,register最贵但是也访问最快。如果实现一个stacked-based的CPU,那么很大一个问题就是不可能造一个很大的放在CPU中的stack,所以时不时还是需要停下来从内存中取数据到on-chip stack,这样反而把性能降低了。

对于解释性语言,是在VM上跑,不是直接在硬件CPU上跑,所以可以不考虑这些问题,虽然有如parrot这样register-based的,但是绝大多数都是stack-based,其中包括MSIL。



放.逐
10月 28, 2006, 9:19 上午
Filed under: 电影电视

据说该片是杜琪峰在没有剧本的情况下拍摄的,老杜给电影公司赚了不少钱,有这样的资本,每隔几年就会有不考虑商业效应的完全自由作品,老板也高兴让他这么搞,因为这样的自由作品最后票房往往还不错,当年的《枪火》就是这样产生的。

一开始有谣言说《放.逐》是《枪火》续集,但是看了就知道只能算是姐妹片,虽然主题差不多,但是情节并不是绝对的延续,主要演员换了一个,但是角色和《枪火》不对应。我觉得《放.逐》不如枪火,虽然单个每段很酷,但是整体拍的有点乱,最后没有组织好。上水木BBS电影版一看,持这种观点的不少,看样子不是只有我一个人这种感觉,但是有几个版霸,只要有人对《放.逐》有点微辞,就是一句话“你不懂老杜”,但也说不出更多,也不知道他们有多懂老杜:)

还有一点让我对老杜有点意见,就是最近他的电影越来越多的掺和政治因素了,从《黑社会》的政治寓言,到《以和为贵》中明显映射大陆对香港的政治控制,这次《放逐》有把情节选择在澳门回归前几天。

不能光说负面的,《放逐》中可圈可点之处不少,太微妙高深需要“懂老杜”的东西我不会,所以说说我凡人能够欣赏得了得方面。

开场,先介绍一下背景。我觉得这段是为了通过内地审查后加上去得,语无伦次,警方既然毫无察觉,怎么又是警方得放逐计划悄然启动,好戏前面加一个狗头。

这估计才是真正得开始,字写得不错:)

老杜的镜头喜欢仰拍,但是不是像苏联阅兵仪式一样为了突出斯大林的高大威猛,因为用远景,都市建筑高高在上,人物反而显得很渺小。下面这个镜头,四个杀手远近错落分布在镜头中,让人想起《枪火》中四人的角色,《放逐》中每个人细节表演部分太少,没有像《枪火》中一样表面出鲜明的性格差异,单靠人物站位体现差异是明显不够的。

然后的枪战,开火的间隙,吴振宇在一团消散的淡蓝烟雾中如鬼魅般出现,真是酷呆了。我们又可以看见这种镜头的处理,人物分别在前景和后景,一个镜头能够涵盖的东西,就没必要分开拍摄,而且1+1>2。

同样的场景,杀手们给本来是猎杀目标的往日兄弟收拾家当,伴随轻松的音乐,让人感觉就是在夕阳下和家人一起给自己的房子大扫除。下面的合影和上面的图对应一下看,场景没有变,但是色调变成暖色调,要的就是这种反差的感觉。

然后这个片子的情节就开始走下坡路了,饭店那一场枪战混乱得很,没有什么可说得。张家辉中枪,众人送他去地下医院,哪知道刚得罪得黑社会老大也因中枪来到,大家先藏在悬挂得帷幔之后,暴露之后被迫现身,掀开帷幔开枪实在是酷,只可惜这样动态得镜头无法通过静态的照片展现全部神韵。

掀开帷幔的一瞬间,世界是旋转的。

另一个角度。

四杀手落难,在荒野上漫无目的。还是这样,人物分散在镜头各个位置,远近不同。

大决战之前,四杀手喝着酒上路,这段我最喜欢,镜头没有怎么移动,演员依次喝酒然后把唯一的酒瓶传给另一个人,巧妙的安排演员的动作,每个杀手在喝酒耍酷的时刻都在镜头最显眼的位置,颇有几分虽万千人吾往矣的气概。

怎么样?似乎林雪最怂,《枪火》里面他可是很酷的哦:)

结尾处几十个人在一个易拉罐落地之前几秒钟的枪战,被宣传的巨酷无比,但是没给我留下深刻映象,因为该片主体和脉络都不是很清晰,这段枪战反而显得像是草草收场。

最后的结局让人唏嘘不已,这时候又出现和前面狗头呼应的狗尾。

谁是“火”啊?黄秋声?吴振宇?张耀杨?还是林雪?情节中没有一点和“卧底”相关的,这完全是忽悠内地电影局用的,真当他们是傻子啊,虽然他们是很傻:)



忙忙碌碌
10月 27, 2006, 3:56 下午
Filed under: 电影电视
这一周都没怎么写blog,因为实在太忙了,倒不至于忙得没时间,而是忙起来属于自己的思维就少了,工作上的事情也不想多说,所以到晚上就算有时间写,也觉得没什么可写。



重游长城
10月 24, 2006, 11:52 上午
Filed under: 工作心情

上个月刚去了一趟长城,这次因为Team的活动又去了一次。

一直觉得长称上有瓦的那种敌楼和长城整体很不和谐,但是让它的屋檐占镜头一角,比单独照城墙更加有韵味。

长城的台阶,踩了这么多年,真是饱经沧桑。拍的时候一个小女孩无意进入镜头了,这样效果更好。



.NET Garbage Collection
10月 22, 2006, 3:06 下午
Filed under: 技术体会

Java也有GC,当然GC也不是Java首创的,可能Sun的出发点就是要把Java搞得open一点,所以很多东西没有做具体规定,比如GC的算法,还有System.GC()的调用按照Java标准,并不会一定引发一次垃圾回收。之后各路Java虚拟机风起云涌,所以当年我作为Java Developer,理直气壮的没有关心GC 内部的具体细节,这不是一个好借口:)

现在在C#上工作,事实上就MS一家的.Net平台(听说还有一个什么Mono),内部原理定义的很明确,容易了解清楚,这也是一家独大的好处:)

有一点要搞清楚,是.NET的GC,不是C#的GC,C#只是产生.NET能够执行代码的语言之一。

C#借鉴了很多C++和Java的东西,对于析构函数,表现得很想C++,也是类名前面加一个~符号,英文叫tlide,但是C#编译器会把这个东西做一些变化,使得表面上很象C++,但骨子里还是按照.NET的规矩做事。

比如我们写一个类的析构函数

~Dummy()
{
    //do something here
}

C#编译器会将其当下面的内容编译

protected override void Finalize()//连函数名都改了哦 
{ 
    try 
    { 
        //do something here 
    } 
    finally 
    { 
        base.Finalize(); 
    }
} 

用ILDASM.exe可以看到产生的最终IL代码中,根本就没有~Dummy这个函数,因为C#编译器自动把它变成protected override void Finalize()了。嗯,Java里面也有一个finalize()函数,似乎就没有怎么被用过。

要是手工添加一个protected override void Finalize()函数,编译器会给一个编译错误:“Do not override object finalize. Instead, provide a destructor.”

如果一个类只涉及内存资源,没有必要自己定义析构函数,因为GC能够在回收对象的时候把内存也回收了;需要自己定义析构函数往往是因为涉及到外部资源(unmanaged resources),如系统文件、unmanaged code分配的内存,这些东西GC自个搞不定,需要类在Finalize中说明白哪些东西要释放。

GC有一个Finalization Queue,对于定义了Finalize的类的对象,创建的时候会在Queue里面挂号,在真正做GC的时候,就对这个Queue里面引用的对象挨个调用Finalize,然后再回收内存。这样保证涉及外部资源对象的“析构函数”在内存释放之前调用,又避免了对不涉及外部资源的类也要调用“析构函数”,所以,不要没事定义一个空的析构函数,这会导致无谓的Finalization Queue的延长,影响效率。

和Java一样,理论上我们不要操心何时做GC,但是也提供了强制做GC的API,Java中的System.gc()只是给虚拟机(VM)一个suggestion,VM可做可不做,VM觉得没必要做我们也末办法:) C#中可用System命名空间中的GC.Collect()来强制做一次垃圾回收,按照字面的说法,.NET肯定会做一次GC,但是不保证所有的“垃圾”真的会在这次行动中被回收,呵呵,这就和Java差不多了。

由于GC的过程需要中断所有正在运行的线程,所以不要频繁的调用GC.Collect(),不然会很影响性能,一般只有确性程序刚刚释放了一大块内存的时候才调用它。我只在写小段test code的时候使用这个API。

还有一个函数GC.WaitForPendingFinalizers(),和GC.Collect()配合使用可以看到明显效果,因为GC.Collect只是引发GC,并不等待GC结束。当然,严格说来GC.WaitForPendingFinalizers()也不是等到GC完成才返回,它实际上等到Finalization Queue上的Finalizer都被调用过了就返回,这时候内存还没有回收呢。

关于GC内部做的事情,还有更高深的,今天研究不完了。




秋游蟒山.采摘
10月 21, 2006, 2:08 下午
Filed under: 山河好大
今天和老婆去参加她公司的秋季采摘节,在蟒山附近,几周不去郊外,秋意盎然,风味不同。

荒草,红叶,绿树。

还有一座大佛,很多游客爬上去拍照,真是罪过。好不容易有那么几秒钟上面没有爬人,赶紧拍了一张。

可惜电池在采摘之前就用光了,没有拍采摘园里面的景色。要说这个采摘这种方式,实在是比较浪费,很多人都是采用采用破坏的方式采摘,磕下来一树枝的苹果,只挑一个红苹果,别的都丢弃掉。

采了五十多个苹果回来,将来几周就有得吃了:)

别人种得东西自己去采成就感不强,以前采自家种的桔子的时候,那是相当的开心啊!



EE & TwC Forum
10月 20, 2006, 2:51 上午
Filed under: 工作心情

昨天微软在在亮马河举行年度Engineering Excellence & Trustworthy Coumputing论坛,

我的同事

我在让同事们拍上面的照片的时候,在场的专业摄像师抢先一步给我们拍了一张,他的专业相机应该拍得更好。
就是下面的摄像师,看他那设备,那姿势,就是专业!

Friedbert Wall,上海Windows Live研发的Director,根据实战讲解研发中的经验教训,讲的是针针见血,值得表扬:)

与会赠送了一个小礼品,表面上看上去是一个饼,其实是一件T恤衫

EE Award Winner。
希望将来我的团队也能拿这个奖。



Http/1.1 Connection Limit: Continue
10月 18, 2006, 1:28 下午
Filed under: 技术体会
使用Fiddler来看看Connection Limit限制下的网络行为,却发现似乎2个连接的限制消失了,关闭Fiddler,限制又出现了。因为这个限制不针对localhost,而Fiddler的工作原理就是在启动的时候偷偷的修改本地的proxy设置,把127.0.0.1:8888作为proxy,作为代理,自然可以截获一切http消息,在退出的时候,把代理又修改回去。测试程序在Fiddler运行的情况下,都是等于和localhost上的一个server通话,没有了这个限制,而相比Fiddler对外的通讯是自己在Socket上的操作,也不让自己受链接限制,所以造成这种现象。