我得到了一个奇怪的观察。
基本上,我正在尝试测量执行长 for 循环的时间。这是我的 C 代码。
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <time.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#define fatal(s, ...) do { printf("%d: errno = %s\n", __LINE__, strerror(errno)); printf(s, ##__VA_ARGS__); exit(-1);}while(0)
#define ts(x) (gettimeofday(&x, NULL))
#define dt(t2, t1) ((t2.tv_sec - t1.tv_sec)*1000000 + (t2.tv_usec - t1.tv_usec))
struct timeval t1, t2;;
#define FORK
int main(int argc, char *argv[])
{
volatile uint32_t d, v, i, j;
pid_t pid;
if(argc != 2)
fatal("./main count\n");
sscanf(argv[1], "%u", &d);
v = 1612 * d;
printf("v= %u\n", v);
#ifdef FORK
if((pid = fork()) != 0) { // running in child or parent gives same result
#endif
ts(t1);
for(j = 0; j < 1000; j++)
for(i = 0; i < v; i++);
ts(t2);
printf("dt = %lu\n", dt(t2, t1));
#ifdef FORK
}
else {
wait(NULL);
}
#endif
return 0;
}
现在,如果我在没有 fork 的情况下测量时间,我得到的时间比在 fork 之后运行相同的东西要长!无论我是在子级还是父级中运行 for 循环都没有关系。起初我以为墙上的时间可能是行为不端,但是我用秒表测量并且 for 循环分叉后实际上执行得更快
示例输出:
$ ./main 100000 // without fork
v= 161200000
dt = 95063417
$ ./main 100000 // with fork
v= 161200000
dt = 82714821
我试过用
taskset
执行,它给出了相同的结果。在我的系统中,我也禁用了超线程,隔离了一个核心并将其频率固定为 2.8 GHz,我观察到同样的现象。我什至在虚拟机 (firecracker) 中运行了相同的实验。我观察到相同的结果(也有外部秒表)!
发生了什么(见鬼)?为什么我得到这样的结果?
uname -a
的输出
Linux csl 5.15.0-58-generic #64~20.04.1-Ubuntu SMP Fri Jan 6 16:42:31 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
lscpu
的输出
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
Address sizes: 48 bits physical, 48 bits virtual
CPU(s): 16
On-line CPU(s) list: 0-15
Thread(s) per core: 1
Core(s) per socket: 16
Socket(s): 1
NUMA node(s): 1
Vendor ID: AuthenticAMD
CPU family: 25
Model: 33
Model name: AMD Ryzen 9 5950X 16-Core Processor
Stepping: 0
Frequency boost: disabled
CPU MHz: 2200.000
CPU max MHz: 5083.3979
CPU min MHz: 2200.0000
BogoMIPS: 6787.45
Virtualization: AMD-V
L1d cache: 512 KiB
L1i cache: 512 KiB
L2 cache: 8 MiB
L3 cache: 64 MiB
NUMA node0 CPU(s): 0-15