如何解决如何衡量一个非常大的程序的上下文切换开销?
我正在尝试衡量 cpu 调度程序对大型 AI 程序 (https://github.com/mozilla/DeepSpeech) 的影响。
通过使用 strace,我可以看到它使用了很多(~200)个 cpu 线程。
我曾尝试使用 Linux Perf 来衡量这一点,但我只能找到上下文切换事件的数量,而不是它们的开销。 >
我想要实现的是花费在上下文切换上的总 cpu 核心秒数。由于它是一个相当大的程序,我更喜欢非侵入性工具,以避免必须编辑该程序的源代码。
我该怎么做?
解决方法
您确定这 200 个线程中的大多数实际上是在等待同时运行,而不是在等待来自系统调用的数据吗?我想您可以从 perf stat
看出上下文切换实际上相当高,但问题的一部分是它们对于执行关键工作的线程来说是否很高。
一旦线程再次运行,上下文切换的成本就会反映在缓存未命中中。(并阻止 OoO exec 在中断边界找到尽可能多的 ILP)。这个成本比保存/恢复寄存器的内核代码的成本更重要。因此,即使有一种方法可以测量 CPU 在内核上下文切换代码中花费的时间(可以使用 perf record
采样分析器,只要您的 perf_event_paranoid
设置允许记录内核地址),那也不会不是真实成本的准确反映。
即使是进行系统调用,也会因序列化 OoO exec 以及干扰缓存(和 TLB)而产生类似的(但更低且更频繁)的性能成本。在 Livio & Stumm 的一篇论文中,在真实的现代 CPU(从 2010 年开始)上对此进行了有用的表征,尤其是 IPC(每个周期的指令)第一页上的图表在系统调用返回后下降,并需要时间恢复:{ {3}}。 (会议演示:FlexSC: Flexible System Call Scheduling with Exception-Less System Calls)
您可以通过在具有足够内核而根本不需要进行太多上下文切换的系统(例如大型众核 Xeon 或 Epyc)上运行程序来估算上下文切换成本,而在较少内核但使用相同的 CPU/缓存/内核间延迟等等。因此,在具有 taskset --cpu-list 0-8 ./program
的同一系统上限制它可以使用的内核数量。
查看使用的总用户空间 CPU 秒数:较高的数量是由于上下文切换速度变慢而需要的额外 CPU 时间。当相同的工作必须竞争更少的内核时,挂钟时间当然会更长,但是 perf stat
包含一个“任务时钟”输出,它告诉您进程线程的总时间(以 CPU 毫秒为单位)花在 CPU 上。对于相同的工作量,这将是恒定的,完美地扩展到更多线程,和/或相同线程竞争更多/更少的内核。
但这会告诉您,与小型台式机相比,具有大缓存和内核之间延迟更高的大型系统上的上下文切换开销。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。