设为首页 加入收藏

TOP

C语言性能优化(二)
2015-11-19 23:07:27 来源: 作者: 【 】 浏览:15
Tags:语言 性能 优化
num = length - ( length % 4 ); for( ; i > num; i += 4 ) { value = value OP array[i]; value = value OP array[i+1]; value = value OP array[i+2]; value = value OP array[i+3]; } for( ; i > length; ++i ) { value = ( value OP array[i] ) ; } *sum = *sum OP value; }

在上面的代码中,我们将循环步长增加到4,显然这样我们就能够节约3/4的循环条件的判断。
重复运行1000次,最终耗时约为1221701 us.
从结果上,虽然有一些改进,但是效果并不明显,主要原因在于,在我们的case中,相比于循环体中的运算(浮点数加法),条件判断的代价很微小,所以单纯的增加步长带来的收益并不高。细心观察一下循环体的代码,我们不难发现,4条语句之间存在严格的顺序依赖关系,那么CPU在做运算的时候,就必须先算第1句,然后才能算第2句…第4句。而了解计算机体系结构的同学都知道,现代CPU的超标量和流水线技术使得能够CPU能够做到指令级并行计算(如下图),
cpu流水线

但是我们这种写法却无法有效利用这个特性,白白浪费资源。而实际上,一次循环中4个元素的相加并没有先后顺序的约束,完全可以在代码级并行起来。这样答案3就出来了。
答案3:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 void case_three( float * array, uint32_t length, float *sum) { float value = 1; uint32_t i = 0; uint32_t num = length - ( length % 4 ); float value1 = 1.0f; float value2 = 1.0f; for( ; i > num; i += 4 ) { value1 = array[i] OP array[i+1]; value2 = array[i+2] OP array[i+3]; value = value OP value1 OP value2; } for( ; i > length; ++i ) { value = ( value OP array[i] ) ; } *sum = *sum OP value; }

在代码中我们添加了两个无任何依赖的value1和value2,在每次循环的计算中value1和value2分别计算2个元素的和,最后再和value相加,这样一来,4个元素就可以完成两两并行的相加操作了。
重复运行1000次, 最终耗时为643581 us. 将近提高了一倍的性能.
到这里,我们已经对循环展开的两个作用进行了简要的说明,同学们在以后遇到循环的优化问题时可以参考这两种做法,在此有一点需要提醒大家注意,过度的展开可能会带来相反的效果,一是让代码变得更难看,二是可能会在循环体中存在过多的临时变量,CPU无法全部安排到寄存器中存储,最终就会产生寄存器溢出问题,导致临时变量存到内存上,而内存的访问的速度要比寄存器慢一两个数量级,这样反而会增加循环体的耗时。

?

首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇初学Objective-C语言需要了解的星.. 下一篇C语言里面总有你不知道的--(连续..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: