---
title: CacheLine优化
description: "CPU标识Cache中的数据是否为有效数据不是以内存位宽为单位，而是以CacheLine为单位。这个机制可能会导致伪共享（false sharing）现象，从而使得CPU的Cache命中率变低。出现伪共享的常见原因是高频访问的数据未按照CacheLine大小对齐。"
url: https://www.hikunpeng.com/document/detail/zh/perftuning/tuningtip/kunpengtuning_12_0052.html
sourcePath: /source/zh/perftuning/tuningtip/kunpengtuning_12_0052.html
indexId: 1b6c56cf4090877290cf817e40dea098a159e12ef6bff4448f260fc1dee41d3d58
---
# CacheLine优化

#### 原理

CPU标识Cache中的数据是否为有效数据不是以内存位宽为单位，而是以CacheLine为单位。这个机制可能会导致伪共享（false sharing）现象，从而使得CPU的Cache命中率变低。出现伪共享的常见原因是高频访问的数据未按照CacheLine大小对齐。

Cache空间大小划分成不同的CacheLine，示意图如图1所示。虽然readHighFreq没有被改写，且存在于Cache中，但在发生伪共享时，仍需从内存中读。

图1 Cache空间大小划分

例如以下代码定义两个变量，会在同一个CacheLine中，Cache会同时读入：

```
int readHighFreq, writeHighFreq
```

其中readHighFreq是读频率高的变量，writeHighFreq为写频率高的变量。writeHighFreq在一个CPU核中被改写后，这个Cache中对应的CacheLine长度的数据被标识为无效，也就是readHighFreq被CPU核标识为无效数据，虽然readHighFreq并没有被修改，但是CPU在访问readHighFreq时，依然会从内存重新加载，出现伪共享导致性能降低。

鲲鹏920和x86的CacheLine大小不一致，可能会出现在x86上优化好的程序在鲲鹏920上运行时的性能偏低的情况，需要重新修改业务代码数据内存对齐大小。x86 L3 Cache的CacheLine大小为64字节，鲲鹏920的CacheLine为128字节。


#### 修改方式

1. 修改业务代码，使得读写频繁的数据以CacheLine大小对齐，修改方法可参考：

  a. 使用动态申请内存的对齐方法：
    1 int posix_memalign(void **memptr, size_t alignment, size_t size)

    调用posix_memalign函数成功时会返回size字节的动态内存，并且这块内存的起始地址是alignment的倍数。

  b. 局部变量可以采用填充的方式：
    1 2 int writeHighFreq; char pad[CACHE_LINE_SIZE - sizeof(int)];

    代码中CACHE_LINE_SIZE是服务器CacheLine的大小，pad变量没有用处，用于填充writeHighFreq变量余下的空间，两者之和是CacheLine大小。

2. 部分开源软件代码中有CacheLine的宏定义，修改宏的值即可。如在Impala使用CACHE_LINE_SIZE宏来表示目标平台的CacheLine大小。
