【问题标题】:Reproducing "Gallery of processor cache effects"再现“处理器缓存效果库”
【发布时间】:2010-10-09 16:24:07
【问题描述】:

阅读 this 文章后,我尝试在我的 Mac 上重现该示例。然而我的第一个例子的曲线看起来完全不同,我不明白为什么..

我的代码如下:

#include <mach/mach_time.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>

void mach_absolute_difference(uint64_t end, uint64_t start, struct timespec *tp) {
    uint64_t difference = end - start;
    static mach_timebase_info_data_t info = {0,0};

    if (info.denom == 0)
        mach_timebase_info(&info);

    uint64_t elapsednano = difference * (info.numer / info.denom);

    tp->tv_sec = elapsednano * 1e-9;
    tp->tv_nsec = elapsednano - (tp->tv_sec * 1e9);
}

int main(void)
{
    int len = 64 * 1024 * 1024;
    int *arr = (int *)malloc(sizeof(int)*len);

    uint64_t start,end;
    struct timespec tp;

    start = mach_absolute_time();
    for (int i = 0; i <len; i += K) 
        arr[i] = 0;
    end = mach_absolute_time();

    mach_absolute_difference(end, start, &tp);

    FILE *fp;
    fp=fopen("simple_array.log", "a+");
    fprintf(fp, "%i\t%ld\t%ld\n", K, tp.tv_sec,
            tp.tv_nsec);
    fclose(fp);

    free(arr);
    return 0;
}

我按照this blog 中的描述测量了时间,希望它是正确的。我还想知道我应该使用什么来测量 Mac 上的执行时间或 CPU 周期。或者更好的是,它会看到某个功能的缓存命中/未命中的数量。然而,Shark 仅以百分比显示 l2 缓存未命中。

在编译为 32 位时更新这个,注意 int 大小从 8 字节变为 4 字节

【问题讨论】:

  • 如果您在汇编程序中对此进行试验会容易得多。这就是为什么使用 C 而不是汇编程序来学习低级概念不好的原因。
  • 我从未使用过 x86 汇编器,目前也没有时间学习它。但是在“处理器缓存效果库”中使用了 C#,它甚至更高级别..
  • 我在重现他的结果时遇到了同样的问题,即使启用了-O0 标志...
  • 你在哪里设置 K 的值?
  • 复制/粘贴代码时可能忘记了。我不记得这个问题是 10 岁。

标签: c macos caching hardware


【解决方案1】:

一些事情:

  • 您的工作循环没有明显的副作用;你确定编译器没有优化部分或全部吗?
  • int 的大小可能不是一个字节
  • K 越大,所做的整体工作就越少(i 达到 len 的迭代次数越少)

【讨论】:

  • 如何确保编译器不会优化掉它?我用 -O0 编译(使用 gcc).. 我猜 int 在 64 位拱门中是 8 个字节
  • 除以 8 可能更有意义。
  • 好吧,曲线(32 位)在 16 之后变得更平坦了。也许我的系统上也有太多噪音。
  • @Nils:在-O0 上,编译器可能没有优化循环(尽管您可以检查反汇编以确定)。但是,最可靠的方法是随后对arr[] 执行某些操作,例如将其写入文件。
猜你喜欢
  • 2015-11-10
  • 1970-01-01
  • 2016-10-12
  • 2019-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-09
相关资源
最近更新 更多