有些事情做起来才知道和想像的完全不一样. 比如优化。
上周开始对解码器做优化和重构。由于要移植,不能用mmx,只能在c/c++层面上做。
2G 赛杨,运行速度大概 32fps左右,不包括显示,而且也不包括deblocking,是相当让人不满意的。profile以后,发现瓶颈是inter predict。我在设计的时候已经用空间换了时间,把所有半象素做了保存(这个设计本身就可能非常有问题,在ref的frame数量太多的时候,会造成极其恐怖的内存消耗,但是我认为我迟早掌握编码器端,可以避免这种情况发生)。在计算第三种半象素的时候,我发现我当时为了正确性,没有利用以前得到的结果(会造成微小误差),这样同时会有多调用clipping的开销,展开循环,除去边界象素,使用以前结果忽视误差,让速度升到55fps。
自此开始噩梦。下一个瓶颈是parse函数,包括了一些predict,predict以后的赋值,还有重头vld。vld算法本身几乎是不太可能优化了,除非我重新组织码表。希望是那些地层I/O函数,被调用了数十万次,而且我没有内联。迅速改成内联,毫无改变???去掉错误处理的跳转,毫无改变???不解。。。再后来想到可能函数本身无法被内联,profile证明想法。改变函数接口,改函数为宏,进步微弱。。。
看parse函数的其他部分,用空间换时间把某些值预先保存,比如mbA,mbB等,再改小函数成内联,用static 数组或者bit计算等手段,全部收效甚微,而且profile出现了半象素计算占用率不确定的情况,最多到18,最小只有6。。。
idct出奇的占用量小,我也不想多改,看了看motion compesation,展开去掉了每次copy时候的clipping,终于有所上升,大概到65左右,而内存到是用的奇多,大概略过7M(向后10 frame的reference体现了保存半象素值的威力)。
郁闷