缓存局部性
由深入理解计算机操作系统一书中,我们可以知道,计算机读取数据的时候并不是直接访问内存。而是先访问缓存,如果缓存不中,再去访问TLB,然后如果不中,才一级一级页表去访问内存。
此片文章主要针对缓存,那我们如果写的代码中是顺序访问的,cpu在读取数据的时候会预读数据到cache中,这样我们命中cache的几率就越大。CacheLine是Cpu Cache的最小缓存单位,x86结构的 cacheline 一般为64字节。那么如果我们在设计类的成员变量的时候,尽可能的把相应成员变量写到每一个64字节内。那么这样就不会发生,一个成员变量的数据在俩个cacheline中,这样就不会跨cacheline来修改数据了。这样就可以提高访存效率。
struct UseCacheLine
{
some * a;
some * b;
some * c;
some * d;
char [aligned] cache_aligned;
something e;
}
上面这个类的设计中,cache_aligned 的这个数组就是用来 填充的,尽可能让abcd在一个cacheline中,这样 e 的数据就不会跨cacheline。
所以一个结构体成员变量的设计,目前我知道的俩个原则:
- 对齐数小的数据尽可能放后面,因为会内存对齐的原因,我们要让无缘用来对齐的内存尽可能小,这样结构体大小就可能小,结果就是节约内存。
- 尽可能的将数据放在一个cacheline中,增加访问cache的效率。