多次基准测试功能 - 首先调用的所有调用都是指令缓存的?

时间:2011-10-19 10:09:24

标签: c benchmarking cpu-cache

我在C中编写了一个小型基准测试库,用于对单个函数进行基准测试。它的工作方式是为基准函数提供指向void函数的指针,不带参数和迭代次数。然后,该函数返回struct,其中包含有关

的信息

然而,当查看单个结果时,我发现第一个呼叫占用了大量时间,然后呼叫占用了很少的时间。

所以我想知道:

  1. 这是由于指令缓存吗?
  2. 如果对第一个问题是肯定的,那么基准测试工具通常如何符合这一要求?第一个电话被排除在外吗?
  3. 如果是第一个问题,是否存在缓存未应用于函数的情况?
  4. 如果对第一个问题是肯定的话,是否会对函数的整个函数或段进行缓存?
  5. 如果对第一个问题是肯定的话,还有什么我应该考虑的,我应该阅读并理解更好吗?

  6. 数据和代码

    检索时间的函数:

    double currentTime()
    {
        struct timeval time;
        struct timezone timezone;
        gettimeofday(&time, &timezone);
        return time.tv_sec + time.tv_usec * 1e-6;
    }
    

    测试结果:

    0.000319
    0.000000
    0.000000
    0.000000
    0.000001
    0.000000
    0.000000
    0.000000
    0.000000
    0.000000
    Total time: 0.000320
    Average time: 0.000032
    Worst time: 0.000319
    Best time: 0.000000
    

    没有优化标志的结果:

    13.425430
    13.349757
    13.482863
    13.129472
    13.020705
    13.672982
    13.027595
    13.139602
    13.028962
    13.107892
    Total time: 132.385260
    Average time: 13.238526
    Worst time: 13.672982
    Best time: 13.020705
    

    正在测试的功能产生了这个结果:

    void test()
    {
        unsigned int i = 0;
        while(i++ < UINT_MAX){}
    }
    

    制作档案:

    CC = gcc
    MAIN = main.c
    SOURCES = lib/tb_time_handling.c lib/tb_rendering.c tb_benching.c
    OUTPUT = main
    FLAGS = -Wall -pedantic -O2
    
    all: main
    
    main: 
        $(CC) $(MAIN) $(SOURCES) -o $(OUTPUT) $(FLAGS)
    

    Github repo包含所有代码:

    https://github.com/Ancide/TinyBench

    编辑:忘记提及编译器和编译器标志

    编辑2:添加了所有代码的git repo以防有人想要查看所有内容

    编辑3:添加没有O2标志的结果

1 个答案:

答案 0 :(得分:1)

这在虚拟内存操作系统中是正常的。对函数的第一次调用往往会生成页面错误,该错误会将可执行文件中的代码加载到RAM中。如果您对实际代码perf感兴趣,则忽略第一个调用。如果您对实际的性能测量感兴趣,那么您不要忽略它。