2009年3月3日星期二

无题

昨天晚上下班的时候,突然感觉颈椎有些痛,吓了我一跳,这么多年来从未有过这样的情况。本来以为睡一觉即可恢复,但是没想到早起还是很痛,也许是昨天休息的很不好,也许是需要一段时间才能恢复。

我想是前一段时间坐姿有些问题,因为连续10天都在电脑前面工作,很少离座,而电脑在我左前方,要侧着头,很不舒服,时间久了就容易出问题。我一早过去,首先就是把显示器板正,但是因为桌面的东西有点多(还有一个笔记本),怎么摆都有些别扭。

本来我打算今天完成VM指令长度精简的工作,到可以提交的程度。没想到今天会议有点多,用掉了4个小时,结果晚上只完成了driver的自测,放到工程中还是有问题,没来得及全部排查,看来只能明天继续了。

我试验了一下压缩指令长度以后的效果,速度居然比以前版本的driver慢了50%,让我有些纳闷。检查了一下,发现我Release版本的优化选项居然没开(应该是以前检查bug时关闭了),打开了O2以后,速度恢复正常了,但是仍然比原先的driver略慢10%。这有一半在我的意料之中,因为指令精简以后,有一些信息不能再简单的获得了,需要通过指针多索引一次。不过我并不打算到此结束,打开调试看了一下汇编代码,发现几个问题:

1. VC O2优化的程度不够
我将值保存进入栈中的局部变量,然后在用这个局部变量作为参数调用。这个局部变量其实应该被优化掉,但是目标代码仍然进行了一个多此一举的mov,也许开更高的优化选项可以解决这个问题,但是我不想冒险,毕竟O2才是久经考验的。我调整了一下C语言代码的组织,去掉了这个局部变量就解决了问题。

2. switch-case不是我期望的工作方式
有一段代码类似如下:
switch (parameters)
{
default:
VM_ASSERT(parameters == 0);
...
break;

case 1:
...
break;

case 2:
...
break;
}
其中parameters只可能是0、1、2。目标实际上是先判断2,然后dec,判断1,最后跳转到default分支。这不是我想要的,因为大部分VM指令都是无参数的,所以这里进行了一下调整:
if (parameters == 0)
{
...
} else
if (parameters == 1)
{
...
} else
{
...
}
同时,我注意到这段代码之前有一段分支,就是判断是否有从另一处取参数(如果指令参数较长,不能保存在指令内,需要另取),如果是则另取参数,然后再执行到这个分支。我考虑了一下,将以上代码复制了一份。这样如果另取参数时,可以减少一次判断(因为不可能有参数0的情况),同时,如果只有一个参数则不需要取第二个参数,节约了一条指令。

进行以上修改以后,执行VM指令的速度提高了将近30%(当然,这是针对简单指令而言的,如果是复杂指令,提高的不会太多),全面超越了之前的版本。

没有评论:

发表评论