缓存使用,空间局部性和延迟

时间:2012-04-26 16:34:43

标签: c caching pthreads parallel-processing localityofreference

我正在学习有关空间局部性的缓存操作。 (到目前为止,我的参考文献是Lin和Snyder的并行编程原理this tutorial,当然还有维基百科。)

使用英特尔酷睿2双核CPU(L7500),在Windows 7 Professional上运行以下使用gcc编译的示例。

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

int main()
{
    int *array;
    int length;
    int count;
    int range;
    int i;

    // generate an array of a million integers between 0 and 99
    length = 1000000;
    range = 100;
    array = calloc(length, sizeof(int));
    srand(time(NULL));
    for(i = 0; i < length; i++)
    {
        array[i] = rand() % range;
        // printf("%d\n", array[i]);
    }

    // count the number of occurrences of 3 in the array
    count=0;
    for(i=0; i<length; i++)
    {
        if(array[i]==3)
        {
            count++;
        }
    }
    printf("count = %6d\n", count);

    return 0;
}

现在在例程的后半部分,将读取整个整数数组,因此每个空间局部性CPU都应该事先将它们加载到缓存中。但是,在循环期间的任何时候,有多少数组可以/可以/应该加载到缓存中?一次一个高速缓存行(64字节/每个int 4个字节= 16个整数),它的大块,或者一举一个整个数组?

另外,据我所知,将数据从RAM加载到缓存(或根据教科书,从非本地内存到本地内存)所涉及的延迟比实际运行例程所需的时间要重要得多。真?

现在说我们将此代码移动到多处理器/多核机器,并将代码的计数部分更改为在4,8,16等并行线程(使用pthreads)中运行,计算数组的不同部分,然后在最后添加私人计数。这会导致多次单独出现RAM到缓存延迟,使并行版本比串行版本运行得慢吗?

1 个答案:

答案 0 :(得分:2)

是的,内存速度和延迟确实在许多算法中占主导地位,因此有必要尽可能高效地使用内存缓存来加速这些算法。

并行运行会影响您的表现,但通常不会。弄清楚这需要大量的测试和调整。

例如,将四核芯片连接到一组RAM。如果算法需要最大速度的内存读取并且计算总是比RAM速度快,那么并行运行将不会获得任何收益,并且可能会减慢速度。

但是如果你有一个双插槽系统,每个CPU都有自己的RAM,算法会加速。

或者,系统可能会从1个RAM库升级到4个,并从单个通道切换到四通道RAM配置。此时,RAM速度可能超过计算速度,四核将从运行更多线程中受益。

在我看来,每个核心运行一个线程通常会让你受益,并会利用系统升级。运行单个线程可以避免少量的同步开销,但将来会一直限制程序。