2

我有一个功能如下:

int doSomething(long numLoop,long arraySize){
    int * buffer;
    buffer = (int*) malloc (arraySize * sizeof(int));
    long k;
int i;

    for (i=0;i<arraySize;i++)           
    buffer[i]=2;//write to make sure memory is allocated
    //start reading from cache
    for(k=0;k<numLoop;k++){
        int i;
        int temp
        for (i=0;i<arraySize;i++)           
        temp = buffer[i];
    }
}

它所做的是声明一个数组并从头到尾读取。目的是看缓存的效果。我期望看到的是:当我调用 doSomething(10000,1000) 时,arraySize 很小,所以它都存储在缓存中。之后我调用 doSomething(100,100000),arraySize 比缓存大。因此,第二个函数调用应该比第一个函数调用花费更长的时间。后一个函数调用涉及一些内存访问,因为整个数组不能存储在缓存中。但是,似乎第二次手术与第一次手术所花费的时间大致相同。那么这里有什么问题呢?我尝试使用 -O0 进行编译,但并没有解决问题。谢谢你。

更新 1:这些是随机访问的代码,它似乎可以工作,大数组的访问时间约为 15 秒,而小数组的访问时间约为 3 秒

int doSomething(long numLoop,int a, long arraySize){
    int * buffer;
    buffer = (int*) malloc (arraySize * sizeof(int));
    long k;
    int i;

    for (i=0;i<arraySize;i++)           
        buffer[i]=2;//write to make sure memory is allocated
    //start reading from cache
    for(k=0;k<numLoop;k++){
        int temp;
            for (i=0;i<arraySize;i++){
                long randnum = rand();//max is 32767
                randnum = (randnum <<16) | rand();
                if (randnum < 0) randnum = -randnum;
                randnum%=arraySize;
                temp = buffer[randnum];
            }
    }
}
4

3 回答 3

2

您正在按顺序访问数组,

for (i=0;i<arraySize;i++)           
    temp = buffer[i];

因此您正在访问的部分将始终在缓存中,因为该模式很难预测。要查看缓存效果,您必须以不太可预测的顺序访问数组,例如通过生成(伪)随机索引,以便在数组的前部和后部之间跳转。

于 2012-09-30T18:03:22.507 回答
1

除了其他答案:您的代码按顺序访问内存。假设高速缓存行是 32 字节。这意味着您可能会在每 8 次访问时获得一次缓存未命中。因此,选择一个随机索引,您应该使其与前一个值相距至少 32 个字节

于 2012-09-30T18:07:47.847 回答
0

为了测量多个调用的效果,您必须使用相同的缓冲区(期望第一次加载缓存,下次使用它)。在您的情况下,您为每个调用分配一个新缓冲区。(此外,您永远不会释放您的分配。)

于 2012-09-30T18:04:55.717 回答