美文网首页开发者内功修炼
内存延迟实际测试

内存延迟实际测试

作者: yanfeizhang | 来源:发表于2019-05-21 09:37 被阅读0次

在前面的文章你能估算出你的内存的访问延时吗?中,我们对内存的访问延迟进行了理论上的研究。那么今天我们实际编写代码进行一下测试。 看一下实践能否和理论匹配的上。
为了衡量各种情况下的内存带宽情况。我们用c写了一个double类型的数组,然后用for循环对其进行遍历,然后统计其每次访问内存平均耗时情况。核心代码如下:

/*
 * 初始化一个指定大小的数组
 * 通过对内存大小不断变化,逐步制造出一级、二级、三级溢出、最后穿透到内存IO的case。
 */
void init_data(double *data, int n){
    int i;
    for (i = 0; i < n; i++) {
        data[i] = i;
    }
}

/*
 * 对内存以指定步长执行顺序访问
 * 这块测试代码有个加法额外开销。算术运算是以CPU周期来计算的,比内存周期要快。
 * 所以本测试中忽略这个算术运算带来的额外开销。
 */
void seque_access(int elems, int stride) {
    int i;
    double result = 0.0; 
    volatile double sink; 

    for (i = 0; i < elems; i += stride) {
        result += data[i];  
    }
    sink = result; 
}
/*
 * 对内存执行随机访问,其中random_index_arr是提前随机好的数组下标。  
 * 这实际比顺序多了一次内存IO,但由于对random_index_arr的访问时顺序的,而且数组要相对小很多。
 * 所以它绝大部分情况下都能命中高速缓存,可以忽略这个小内存IO对主测试过程的影响。
 */
void random_access(int* random_index_arr, int count) { 
    int i;
    double result = 0.0; 
    volatile double sink; 

    for (i = 0; i < count; i++) {
        result += data[*(random_index_arr+i)];  
    }
    sink = result; 
}

实验结果数据

注意,不同的机器的实验数据会略有差异。越新的机器数据表现越好,因为硬件参数不一样,但是偏差不会太大。

case 1: 内存2k,步长从1到64

步长(字节) 延迟(ns)
1 1.28
9 1.28
17 1.33
25 1.35
33 1.30
41 1.41
49 1.45
57 1.40
64 1.27

结论:内存足够小的时候,一级高速缓存完全能装的下,因此绝大部分的请求都是一级缓存IO,内存IO并没有怎么进行。所以无论步长怎么变化,延迟基本都在1ns左右。

case2:内存从8k到64M,步长固定8

内存大小 延迟(ns)
8k 1.32
32k 1.27
64k 1.73
256k 2.03
512k 2.62
2m 2.62
8m 2.88
16m 5.17
64m 5.84

结论:内存越来越大,CPU的高速缓存逐渐hold不住了,越来越多的请求穿透到了内存。延迟已经逐步接近真实的内存IO了

case3:内存从8k到64M,步长固定64

内存大小 延迟(ns)
8k 1.25
32k 1.25
64k 1.74
256k 2.03
512k 2.47
2m 2.47
8m 3.29
16m 7.73
64m 8.89

结论:步长从case2的8增加到了本case的64以后,空间局部性进一步被打乱。内存在2m以下的时候,延迟没有太大变化。因为虽然局部性乱,但CPU缓存都能hold住,穿透到内存的情况不多。但当内存编程8m或者64m的情况下,高速缓存命中率就会降低,因此平均延迟也增加到了9ns左右。这个数字其实就是内存在顺序IO时的大概耗时。

case4 内存8k到64m,彻底随机访问

内存大小 延迟(ns)
8k 2.40
32k 2.40
64k 2.40
256k 2.40
512k 4.80
2m 4.80
8m 19.20
16m 24.0
64m 38.40

结论:当彻底随机访问以后,不光是穿透到内存的IO变多了,而且穿透到内存的IO也增大了行地址变化的概率。也就是说内存IO也不能以高效的顺序IO进行了,更多的请求进行的是行列地址都变了的随机IO。因此64m的情况下,内存IO延迟增加到了将近40ns

最终结论

  • 内存顺序IO延迟在9ns左右
  • 内存随机IO延迟在40ns左右
  • 如果程序局部性写的足够好,操作系统会帮你用CPU缓存访问减少低效的内存IO。

个人公众号“开发内功管理”,打通理论与实践的任督二脉。

相关文章

网友评论

    本文标题:内存延迟实际测试

    本文链接:https://www.haomeiwen.com/subject/tgtnaqtx.html