c语言中实现字符串的大小的比较_测试cache大小-C语言实现

7ba86ee08b69c530d6760dfa8f2722cf.png

1. 简介

在实际CPU从内存中取数时很多时候从cache中存取,在这个实验中使用C语言编成估计cache的大小。

2. 实验思路

当一个数组的大小超过cache的大小时,随机读取数组的元素会发生cache的替换现象。如果要存取的数据经常不在cache中(被替换出去/没有载入),CPU需要多次从内存中读取数据。

从内存中读取数据的时间远大与从cache中读取的时间,因此从如果数组大于cache size那么多次随即读取的时间会增加。当随即读取时间出现显著增加时,数组的大小即为cache size的估计量。

3. 代码

代码本身比较简单。注释也都比较详细,直接上代码。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

#define READ_TIMES 999999999
#define TEST_RANGE 24

int main()
{
    int i;
    // 每次要测试的内存块大小
    int *block_size = (int *)calloc(TEST_RANGE, sizeof(int));
    for (i = 0; i < TEST_RANGE; ++i)
        block_size[i] = pow(2, i);

    srand(time(NULL));
    // 每次循环测试大小为block_size[i]的数组随即读取的时间
    for (i = 0; i < TEST_RANGE; ++i)
    {
        // 用size代替block_size[i]减少代码量
        int size = block_size[i];
        // 创建大小为block_size[i]的数组
        int *block = (int *)calloc(size, sizeof(int));

        int j, temp;
        clock_t start = clock(), total_time;
        // 开始随即读取
        for(j = 0; j < READ_TIMES; ++j)
            temp += block[rand() % size];
        total_time = clock() - start;

        // 由于数组是int类型,因此最终大小要乘 sizeof(int)
        printf("At size: %ldB, we need %lf secn", size * sizeof(int),
            (double)total_time / CLOCKS_PER_SEC);
    }
    return 0;
}

4. 运行结果

得到的运行结果如下

At size: 4B, we need 8.686316 sec
At size: 8B, we need 8.830951 sec
At size: 16B, we need 8.271359 sec
At size: 32B, we need 8.633918 sec
At size: 64B, we need 8.209328 sec
At size: 128B, we need 8.174642 sec
At size: 256B, we need 8.257708 sec
At size: 512B, we need 8.429885 sec
At size: 1024B, we need 8.398997 sec
At size: 2048B, we need 8.389903 sec
At size: 4096B, we need 8.349263 sec
At size: 8192B, we need 8.603128 sec
At size: 16384B, we need 8.294702 sec
At size: 32768B, we need 8.382414 sec
At size: 65536B, we need 8.452870 sec
At size: 131072B, we need 8.577709 sec
At size: 262144B, we need 8.493697 sec
At size: 524288B, we need 8.535531 sec
At size: 1048576B, we need 8.457926 sec
At size: 2097152B, we need 8.466891 sec
At size: 4194304B, we need 8.602997 sec
At size: 8388608B, we need 8.984190 sec
At size: 16777216B, we need 9.560884 sec
At size: 33554432B, we need 10.243553 sec

可以看到在数组大小为8388608 Byte时随机读取的时间发生了比较大的增长。因此可以估计cache的大小为4184304 Byte。

5. 验证

为了验证实验的结果,使用命令

getconf -a | grep CACHE

来获得机器的硬件信息。得到的输出如下:

LEVEL1_ICACHE_SIZE                 65536
LEVEL1_ICACHE_ASSOC                4
LEVEL1_ICACHE_LINESIZE             64
LEVEL1_DCACHE_SIZE                 32768
LEVEL1_DCACHE_ASSOC                8
LEVEL1_DCACHE_LINESIZE             64
LEVEL2_CACHE_SIZE                  524288
LEVEL2_CACHE_ASSOC                 8
LEVEL2_CACHE_LINESIZE              64
LEVEL3_CACHE_SIZE                  4194304
LEVEL3_CACHE_ASSOC                 16
LEVEL3_CACHE_LINESIZE              64
LEVEL4_CACHE_SIZE                  0
LEVEL4_CACHE_ASSOC                 0
LEVEL4_CACHE_LINESIZE              0

可以看到L3-cache的大小为4194304 Byte。因此上面估计的cache大小可以接受。

6. 讨论

实际上可以看到数组大小到达4194304 Byte时随即读取的总时间也比较大,这可能是cache替换时出现抖动引起的。

在没有超过cache size时,随机读取时间也有一定的波动,可能有如下原因: (1)电脑上其他程序占用了一定的资源,并且每时每刻占用的资源大小不一样; (2)在数组比较小的时,存取时间可能受到指令的局部性的影响。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值