性能优化简记四(C语言

  在现代处理器架构中,为了加快CPU的读取数据速度,CPU采用了多级缓存机制。CPU访问缓存花费的时间要远远小于访问内存的花费的时间。利用程序空间局部性的性质,简单解释就是,如果程序当前操作内存区域A,那么有很大的概率程序后面还会操作区域A。CPU把最近用过的数据暂存在缓存中,后面需要时,直接在缓存中读取即可。

  上面显示有三级cache,其中index0和index1都属于cache 1,一个是I-cache(指令缓存,存储指令),一个是D-cache(数据缓存,存储数据)。可以通过下面的命令查看等级:

  缓存是由cache line为最小单位组成的,每次从下级缓存中读取整个cache line。缓存行为2的整数幂个连续字节,一般为32-256个字节。最常见cache line的长度一般为64字节。在linux中可以通过下面的命令查看cache line的长度。

  对于热点区域,可以cache line对齐,来减少cache 读取的次数。如下面的图一,数据长度小于cache line,但是在空间上占用两块cache line。一个cache line的后半部分,一个cache line的前半部分,想要完整的读取该数据需要两次读取。

  通过内存调整,使数据只占用一行cache line,则只需要读取一次即可。

  如何移动数据使数据占用一个cache line呢?以cache line的长度为64为例,cache line从内存中读取时,是以64(也就是cache line的长度)的倍数的地址起,连续读取cache line长度,如首地址为0,64,128等,不会从1,2等地址开始读取64字节。 所以只要数据起始内存地址也是64的倍数,则占用的cache line数量保证最小。

  如何使内存首地址按给定大小对齐呢?一般有两个方法,第一个是使用函数aligned_alloc,类似malloc,可以使用man查看函数说明如下:

  属于C11的stdlib.h库。第一个参数是首地址对齐参数,第二个是申请内存大小,说明上要求是第一个参数大小的倍数,但在实际中不是倍数也能正常运行。aligned_alloc(128, 64)说明申请64字节的大小,首地址按照128的倍数对齐。

  如果对上面的方法不放心,还可以手动对齐。原理是先申请一块大的内存,然后手动保证首地址对齐。

发表评论

电子邮件地址不会被公开。 必填项已用*标注