0

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

但是,在查看单个结果时,我发现第一次调用占用了很多时间,然后调用之后占用了很少的时间。

所以我想知道:

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

数据和代码

检索时间的函数:

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 存储库:

https://github.com/Ancide/TinyBench

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

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

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

4

1 回答 1

1

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

于 2011-10-19T12:21:11.160 回答