CPU标识Cache中的数据是否为有效数据不是以内存位宽为单位,而是以Cacheline为单位。这个机制可能会导致伪共享(false sharing)现象,从而使得CPU的Cache命中率变低。出现伪共享的常见原因是高频访问的数据未按照Cacheline大小对齐。
Cache空间大小划分成不同的Cacheline,示意图如图1所示。readHighFreq虽然没有被改写,且在Cache中,在发生伪共享时,也是从内存中读。
例如以下代码定义两个变量,会在同一个Cacheline中,Cache会同时读入:
int readHighFreq, writeHighFreq
其中readHighFreq是读频率高的变量,writeHighFreq为写频率高的变量。writeHighFreq在一个CPU core里面被改写后,这个cache中对应的Cacheline长度的数据被标识为无效,也就是readHighFreq被CPU core标识为无效数据,虽然readHighFreq并没有被修改,但是CPU在访问readHighFreq时,依然会从内存重新导入,出现伪共享导致性能降低。
鲲鹏920和x86的Cacheline大小不一致,可能会出现在x86上优化好的程序在鲲鹏920上运行时的性能偏低的情况,需要重新修改业务代码数据内存对齐大小。x86 L3 cache的Cacheline大小为64字节,鲲鹏920的Cacheline为128字节。
int posix_memalign(void **memptr, size_t alignment, size_t size)
调用posix_memalign函数成功时会返回size字节的动态内存,并且这块内存的起始地址是alignment的倍数。
int writeHighFreq; char pad[CACHE_LINE_SIZE - sizeof(int)];
代码中CACHE_LINE_SIZE是服务器Cacheline的大小,pad变量没有用处,用于填充writeHighFreq变量余下的空间,两者之和是CacheLine大小。