从一个简单的例子体会ARM环境下的C代码优化

    技术2022-05-11  123

    最近花了一些时间致力于ARM下的图像处理代码优化,涉及到不少底层刷新LCD的framebuffer部分。经过一些性能数据测试和代码分析,发现写内存的确是一个瓶颈。因为ARM下面读写内存操作需要按4字节对齐,我所处理的图像数据又都是24bit的,这是典型的不对齐数据。所以刚开始设计的时候,让24位的像素数据本来是一个字节一个字节地刷新的。本能地觉得这样做速度会比较慢,于是记录了一下相关的性能数据,供以后对比分析用。接下来,我又结合前段时间研究的一些文章,对相应的刷新framebuffer部分的算法进行了一些小的改写,主要是处理了像素的写入操作部分,把相邻的两个像素的相关部分合并起来,4字节一次地刷新,比如,第一像素占了24位,然后把第二个像素的低8位合并在一起,构成一个32位的数据进行内存写入。把改进之后的算法测得的数据一对比,发觉速度竟然快了1/2!

    整个操作除了内存刷新,还设计到其他像素处理操作,改进前和改进后的代码,每次执行的ARM指令条数大致都差不多。仔细分析了一下,改进之后的算法,对内存的写次数为原来的1/4,读写内存相对寄存器来说是很慢的,在嵌入式系统上面也更如此,所以,仅仅合并内存的读写操作,就可以很大程度地提高程序的性能。想想也是,SIMD指令也是用的这类原理,只是一次性处理的数据更多而已。

    接下来,我对代码进行了进一步的改进,针对相邻两个像素的不同组合,增加了一些分支处理,虽然代码的体积增大了,但是对于不同的情况,代码进入不同的分支,减少了每次代码执行的时间,速度得到了进一步提高,代码的执行速度比最初的设计快了80%。整个函数都是用C写的,如果用WMMX写(因为用的是PXA27x平台,支持WMMX指令),速度应该会提升得更多。


    最新回复(0)