C loop的缓存优化:为什么这不起作用?

时间:2013-11-24 10:34:47

标签: c caching optimization nested-loops

我正在尝试复制本文的第一段代码

http://www.drdobbs.com/parallel/cache-friendly-code-solving-manycores-ne/240012736

即:

static volatile int array[Size];
static void test_function(void)
{
    for (int i = 0; i < Iterations; i++)
        for (int x = 0; x < Size; x++)
          array[x]++;
}

我使用Ivy Bridge处理器在OS X上运行,因此具有64KiB的L1缓存。但是,无论我在阵列大小周围进行多少更改,都需要相同的时间。这是我的代码:

#define ARRAY_SIZE 16 * 1024
#define NUM_ITERATIONS 200000

volatile int array[ARRAY_SIZE];

int main(int argc, const char * argv[])
{
    for (int i = 0; i < NUM_ITERATIONS; i++)
        for (int x = 0; x < ARRAY_SIZE; x++)
            array[x]++;
    return 0;
}

现在,根据文章建议的逻辑,array应该是64KiB并利用我所有的L1缓存。但是,我尝试使用ARRAY_SIZE(最多160 * 1024)的许多不同组合,相应地设置NUM_ITERATIONS,但每个组合花费相同的时间。

我正在使用gcc -o cachetest cachetest.c进行编译,没有其他选项。即使使用了volatile,还有一些我不知道的优化吗?或者有这么多并行进程和上下文切换,我甚至无法分辨?这里发生了什么?我很困惑。

非常感谢!

1 个答案:

答案 0 :(得分:1)

有两件事:

  • 编译器可能会对您的代码进行一些默认优化
  • 您的代码在任何其他代码/函数中都不使用array,它只会在循环内增加数组值,因此编译器可以通过将程序更改为什么都不做(只返回0)来更优化它,这是仍然是正确的。

我建议:

  • 在循环中添加更多代码,这样编译器就不会消除你的代码,例如:printf数组值,或者将数组值添加到sum变量,然后在循环结束时打印sum变量。
  • 使用-O0选项编译时关闭所有编译器优化。
  • 使用-S选项
  • 检查编译器生成的代码的汇编文件