问题描述
我在具有 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
- 一级缓存:32K d 和 32K i
- 二级缓存:1024K
- 三级缓存:28160K
- 内核:3.10.0-693.2.2.rt56.623.el7.x86_64 #1 SMP PREEMPT 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。
时钟的平均时间约为 500.5 微秒。预计会有波动。
- 这是结果的完整 30 分钟视图。
- 结果中有四个峰值。第一个峰值是预期的,因为这是第一次数据来自主内存并且 cpu 处于睡眠状态。
- 除了第一个峰值之外,还有另外三个峰值,peak_3 和 peak_2 之间的时间差为 11.99364 分钟,其中 peak_4 和 peak_3 之间的时间差为 11.99358 分钟。 (我假设时钟是 500 微秒)
如果我进一步放大:
- 此图显示了 5 分钟内发生的事情。
如果我进一步放大:
- 此图显示了大约 1.25 分钟内发生的事情。
- 您注意到乘法的平均时间约为 113 微秒,并且到处都有峰值。
如果我进一步放大:
- 这张图片展示了 20 秒内发生的事情。
如果我进一步放大:
- 此图显示了 500 毫秒内发生的事情
- ~112.6 微秒是这里的平均时间,完整数据在 1 微秒范围内。
这是我的问题:
- 鉴于 L3 缓存足以存储完整的可执行文件,并且没有正确读取的文件,并且机器上没有其他任何东西在运行,也没有发生上下文切换,为什么有些执行需要几乎翻倍(或有时超过两倍)时间? [查看第一个结果图像中的峰值]
- 如果我们忘记了第一张图像中的那四个峰值,我该如何用几乎恒定的时间差来证明结果中的周期性峰值? cpu有什么作用?这些周期性峰值持续几毫秒。
- 我希望结果像最后一张图片一样接近恒定。有没有什么方法或操作系统/cpu 设置可以让我像最后一张图片一样无限时间运行代码?
完整代码如下: https://github.com/sghoslya/kite/blob/main/multiThreadProfCheckArray.c
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)