引言
最近在学习SPDK开发,其中有个重要概念就是通过RTC(Run To Completion)单线程模式减少上下文切换,增加cache命中率,从而提高整体性能。CPU访问cache的速度理论上比访问内存的速度高两个数量级,今天我就实测一下,cache对程序到底有多大的影响。
环境介绍
我的电脑CPU cache现状通过lscpu命令显示如下:
其中L1d和L1i分别是一级数据cache和一级指令cache,由于是4 core CPU,所以每个core的缓存数是上图数值除以4。也可以通过如下指令查看每个core的缓存数
cat /sys/devices/system/cpu/cpu0/cache/index0/size
48K
cat /sys/devices/system/cpu/cpu0/cache/index1/size
32K
其中index0代表数据cache,index1代表指令cache。cache line是cache操作的最小单元,在我的电脑上是64字节。
cat /sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size
64
cat /sys/devices/system/cpu/cpu0/cache/index1/coherency_line_size
64
实验宗旨就是构造场景尽可能命中CPU的数据cache和不命中两种情况的对比。
实施测试
实验采用golang,测试代码如下:
const SIZE = 10240
var arrays [SIZE][SIZE]uint64
now := time.Now()
for i := 0; i < SIZE; i++ {
for j := 0; j < SIZE; j++ {
arrays[i][j] = 0
}
}
slog.Info("cache version", zap.Int64("value", time.Since(now).Milliseconds()))
now = time.Now()
for i := 0; i < SIZE; i++ {
for j := 0; j < SIZE; j++ {
arrays[j][i] = 0
}
}
slog.Info("no cache version", zap.Int64("value", time.Since(now).Milliseconds()))
上述代码重复执行100次,得出如下结果
场景 | 平均值(ms) | 标准差(ms) |
---|---|---|
cache version | 79 | 25 |
no cache version | 1079 | 31 |
总结
从实验结果看,充分利用数据cache,性能至少是1个数量级的提升,但是标准差不小,即性能波动较大。以上构造的是比较理想化的场景。个人感觉,实际开发中减少CPU上下文切换是cache命中的大前提,同时尽量按照内存地址顺序访问,让每次从内存读取的64字节(cache line size)都能为程序使用,这样就可以最大化利用cache提升性能。
有疑问加站长微信联系(非本文作者)