当前位置: 技术问答>linux和unix
关于代码优化的问题
来源: 互联网 发布时间:2016-08-12
本文导语: 昨天优化一个分布式渲染的代码,优化的部分是对每一帧图像进行处理的部分,总共做了两处改动:一是将原来每次在函数中开辟的缓冲区改为全局变量,即只在第一次初始化是开辟好(因为窗口大小不变,所以每帧...
昨天优化一个分布式渲染的代码,优化的部分是对每一帧图像进行处理的部分,总共做了两处改动:一是将原来每次在函数中开辟的缓冲区改为全局变量,即只在第一次初始化是开辟好(因为窗口大小不变,所以每帧图像需要的缓冲大小不变),这样避免了每次函数调用时分配内存空间和释放的时间代价;而是将原来函数中对全局变量的调用全部用局部变量缓冲,比如原来代码是这样:
int a;
void ....(...)
{
//调用a的代码
}
改为:
int a;
void ....(...)
{
int b=a;
//调用b的代码
}
全局变量有大概6,7个左右。
最后效果如下:
优化前帧率:11-12
第一种优化后:11-13
第二种优化后:18-20
我的问题是这种现象是怎么造成的,我原本觉得内存分配和释放是很费时的事,但实际优化后效果不明显;而第二种优化方案是在看一本国外文献时作者在讲他的一个项目是提到的,说是这么做可以提高cache的命中率。请问这个有没有更具体些的解释,或者这方面的知识属于什么范畴,有没有相关的书籍或领域。请教达人指教,鄙人不胜感激。
int a;
void ....(...)
{
//调用a的代码
}
改为:
int a;
void ....(...)
{
int b=a;
//调用b的代码
}
全局变量有大概6,7个左右。
最后效果如下:
优化前帧率:11-12
第一种优化后:11-13
第二种优化后:18-20
我的问题是这种现象是怎么造成的,我原本觉得内存分配和释放是很费时的事,但实际优化后效果不明显;而第二种优化方案是在看一本国外文献时作者在讲他的一个项目是提到的,说是这么做可以提高cache的命中率。请问这个有没有更具体些的解释,或者这方面的知识属于什么范畴,有没有相关的书籍或领域。请教达人指教,鄙人不胜感激。
|
这个涉及到cache的知识。
绝大部分CPU都有一个cache,许多CPU还有二级cache(相对于一级cache,二级cache容量大一些,但是速度慢一些)。如果在访问数据时,数据没有在cache中,则成为cache没有命中(cache miss),这是需要将数据从内存加载到cache中,这个过程非常慢,因此要尽量保证cache的命中。
如果提高cache的命中率呢?
要将频繁访问的数据集中存放:将频繁访问的数据按照顺序保存,而不要使用指针。这样,最常用的数据会尽可能的保存在一级cache中。
顺序访问数据:在cache miss后,包含需要访问数据在内的一段数据会被加载到cache中,如果顺序访问,就可以提高cache的命中。
避免同时遍历多个比较大的数据buffer:多个缓冲区在cache上互相冲突对导致cache miss的概率提高。
而在本例中,在进入函数的时候,cache里面一般情况下是么没有保存a的值的(因为a是全局的,可能很长时间都没有使用了)。而使用b=a,a依然不會进入cache,但是b会进入cache,这样CPU访问速度会快很多。
绝大部分CPU都有一个cache,许多CPU还有二级cache(相对于一级cache,二级cache容量大一些,但是速度慢一些)。如果在访问数据时,数据没有在cache中,则成为cache没有命中(cache miss),这是需要将数据从内存加载到cache中,这个过程非常慢,因此要尽量保证cache的命中。
如果提高cache的命中率呢?
要将频繁访问的数据集中存放:将频繁访问的数据按照顺序保存,而不要使用指针。这样,最常用的数据会尽可能的保存在一级cache中。
顺序访问数据:在cache miss后,包含需要访问数据在内的一段数据会被加载到cache中,如果顺序访问,就可以提高cache的命中。
避免同时遍历多个比较大的数据buffer:多个缓冲区在cache上互相冲突对导致cache miss的概率提高。
而在本例中,在进入函数的时候,cache里面一般情况下是么没有保存a的值的(因为a是全局的,可能很长时间都没有使用了)。而使用b=a,a依然不會进入cache,但是b会进入cache,这样CPU访问速度会快很多。