我正在具有 RT 优先级的专用 CPU 上循环运行代码以进行多次迭代,并希望长时间观察其行为。我发现代码有一个非常奇怪的周期性行为。
简而言之,这就是代码的作用:
Arraythread
{
while(1)
{
if(flag)
Multiply matrix
record time;
reset flag;
}
}
mainthread
{
for(30 mins)
{
set flag;
record time;
busy while(500 μs)
}
}
以下是我正在使用的机器的详细信息:
- CPU:Intel(R) Xeon(R) Gold 6230 CPU @ 2.10 GHz
- L1 缓存:32K d 和 32K i
- 二级缓存:1024K
- 三级缓存:28160K
- 内核:3.10.0-693.2.2.rt56.623.el7.x86_64 #1 SMP 抢占 RT
- 操作系统:CentOS
- 当前活动配置文件:延迟性能
- 我将Linux实时调度(sched_rt_runtime_us)的全局限制从95%修改为100%
- 上述两个线程都绑定在单个 NUMA 节点上,每个线程的优先级均为 99
有关代码的更多详细信息:
- 主线程每 500 μs 设置一个标志。我使用 CLOCK_MONOTOMIC_RAW 和 Clock_gettime 函数来读取时间(假设为 T0)。
- 我将所有变量放在一个结构中以减少缓存未命中。
- Arraythread 运行一个繁忙的 while 循环并等待设置标志。
- 一旦设置了标志,它就会将两个大数组相乘。
- 乘法完成后,它会重置标志并记录时间(假设为 T1)。
- 我运行这个实验 30 分钟(= 3600000 次迭代)
- 实验结束后,我测量时间差 T1-T0。
Here is the clock:
时钟的平均时间约为 500.5 微秒。预计会有波动。
Here is the time taken by the array multiplication:
- 这是完整的 30 分钟结果视图。
- 结果中有四个峰值。第一个峰值是预期的,因为数据第一次来自主内存并且 CPU 处于睡眠状态。
- 除了第一个峰值之外,还有三个峰值,peak_3 和peak_2 之间的时间差为11.99364 分钟,其中peak_4 和peak_3 之间的时间差为11.99358 分钟。 (我假设时钟为 500 微秒)
如果我进一步放大:
如果我进一步放大:
- 此图显示了大约 1.25 分钟内发生的情况。
- 您注意到乘法的平均时间约为 113 微秒,并且到处都有峰值。
如果我进一步放大:
如果我进一步放大:
- 此图显示了 3.5 秒内发生的情况。
- 这些峰值的起始线之间的时间差为:910 ms、910 ms、902 ms(假设两个连续点相差 500 μs)
If I zoom it further:
- 此图显示了 500 毫秒内发生的情况
- ~112.6 μs 是此处的平均时间,完整数据在 1 μs 范围内。
这是我的问题:
- 鉴于 L3 缓存足以存储完整的可执行文件,并且没有文件读取权限,并且机器上没有其他任何东西正在运行,也没有发生上下文切换,为什么某些执行几乎需要双倍时间(或者有时超过两倍)时间? [查看第一个结果图像中的峰值]
- 如果我们忘记第一张图像中的这四个峰值,我如何证明结果中的周期性峰值具有几乎恒定的时间差? CPU 的作用是什么?这些周期性峰值持续几毫秒。
- 我预计结果会像最后一张图片一样接近恒定。有没有一种方法或操作系统/CPU 设置可以应用来像最后一个图像一样无限时间地运行代码?
这是完整的代码:
https://github.com/sghoslya/kite/blob/main/multiThreadProfCheckArray.c https://github.com/sghoslya/kite/blob/main/multiThreadProfCheckArray.c
None
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)