Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 如何测量大型程序的上下文切换开销?_Multithreading_Profiling_Perf_Microbenchmark_Context Switch - Fatal编程技术网

Multithreading 如何测量大型程序的上下文切换开销?

Multithreading 如何测量大型程序的上下文切换开销?,multithreading,profiling,perf,microbenchmark,context-switch,Multithreading,Profiling,Perf,Microbenchmark,Context Switch,我试图测量CPU调度程序对大型AI程序()的影响 通过使用strace,我可以看到它使用了大量(~200)个CPU线程 我曾尝试使用LinuxPerf来衡量这一点,但我只能找到上下文切换事件的数量,而不能找到它们的开销 我试图实现的是用于上下文切换的CPU核心总秒数。由于它是一个相当大的程序,我更喜欢非侵入性工具,以避免编辑该程序的源代码 我如何才能做到这一点?您确定这200个线程中的大多数实际上都在等待同时运行,而不是等待来自系统调用的数据吗?我想你可以从perf stat中看出,上下文切换实

我试图测量CPU调度程序对大型AI程序()的影响

通过使用strace,我可以看到它使用了大量(~200)个CPU线程

我曾尝试使用LinuxPerf来衡量这一点,但我只能找到上下文切换事件的数量,而不能找到它们的开销

我试图实现的是用于上下文切换的CPU核心总秒数。由于它是一个相当大的程序,我更喜欢非侵入性工具,以避免编辑该程序的源代码


我如何才能做到这一点?

您确定这200个线程中的大多数实际上都在等待同时运行,而不是等待来自系统调用的数据吗?我想你可以从
perf stat
中看出,上下文切换实际上相当高,但部分问题是对于执行关键工作的线程来说,它们是否很高

一旦线程再次运行,上下文切换的代价将反映在缓存未命中中。(并阻止OoO exec在中断边界处找到尽可能多的正确位置)。这个成本比保存/恢复寄存器的内核代码的成本更重要。因此,即使有一种方法可以测量CPU在内核上下文切换代码中花费了多少时间(只要
perf record
sampling profiler允许
perf\u event\u paranoid
设置允许记录内核地址,就可以使用
perf record
采样探查器),这也不能准确反映真正的成本

即使进行系统调用,序列化OoO exec也会带来类似(但更低、更频繁)的性能代价,同时还会干扰缓存(和TLB)。Livio&Stumm在一篇论文中对真实的现代CPU(2010年起)进行了一个有用的描述,特别是IPC(每个周期的指令)第一页上的图表在系统调用返回后下降,并且需要时间恢复:。(会议介绍:)


您可以通过在具有足够内核的系统上运行该程序来估算上下文切换成本,该系统完全不需要进行上下文切换(例如,大量多核Xeon或Epyc),而不是在较少的内核上运行,但具有相同的CPU/缓存/核心间延迟等。因此,在具有
任务集的同一系统上--cpu列表0-8./program
来限制它可以使用多少内核

看看所使用的总用户空间CPU秒数:较高的数量是由于上下文切换速度减慢而需要的额外CPU时间。当相同的工作必须竞争更少的内核时,挂钟时间当然会更高,但是
perf stat
包含一个“任务时钟”输出,它告诉您进程线程在CPU上花费的总时间(以CPU毫秒为单位)。对于相同的工作量,这将是不变的,可以完美地扩展到更多线程,和/或竞争更多/更少内核的相同线程


但是,这会告诉你在一个大系统上的上下文切换开销,这个大系统具有大缓存,内核之间的延迟比在一个小桌面上要高。

你是对的,线程可能在等待数据并自愿地让CPU处理,从而导致上下文切换。我有没有办法把这种情况与计时器中断引起的非自愿的上下文切换区分开来?我还没有找到一种计算计时器中断的方法…@Azuresonance:计算计时器中断无论如何都没有用,因为除非你运行的是一个无滴答的内核,不是每个计时器中断都会导致上下文切换。您可以通过查看平均负载(
uptime
top
)来大致了解平均有多少任务正在运行,或者如果它们有可用的CPU,将运行多少任务。但我认为这也包括D状态下的任务(磁盘睡眠);IDK,如果这是一个因素的话。@Azuresonance:我不知道如何计算非自愿的上下文切换。比如,你可以用
perf stat
计数并减去
yield()
futex()
系统调用的数量?当然,因为需要等待锁而睡眠可能意味着其他线程在持有锁时进入睡眠状态,或者只是在其关键区域内花费了很长时间。在持有锁的情况下睡觉会放大由于代码试图使用比您更多的内核而导致的上下文切换的数量。(大多数好的多线程代码都会根据可用的内核选择许多线程)将性能记录方法与您可能能够隔离开始/结束的方法相结合。我不确定你是如何得到上下文切换代码的地址的。@Noah:是的,
perf record
使用
perf\u SAMPLE\u ADDR
如果
perf\u event\u paranoid
允许的话。Linux的上下文切换代码是
switch\u to()
,由
schedule()
调用。(不过,实际的用户空间寄存器保存/还原在内核入口/出口中,除了SIMD/FP寄存器,它们在现代Linux中急切地保存/还原在上下文切换上,至少在x86中是如此。所以
switch_to()
只需更改当前整数寄存器,包括内核堆栈指针,并保存/还原FP状态。如果是新进程,则CR3页表(而不仅仅是线程)是否要测量内核中的总时间(即包括内核执行IO的时间)还是只是执行上下文切换的时间?@Noah只是执行上下文切换的时间。我的最终目标是:我有一个在内核中花费大量时间的程序,我希望详细分析这段时间(例如,x%花在系统调用上,y%花在上下文切换上,等等)。我知道系统调用时间可以通过
strace
来衡量。但我不知道如何测量上下文切换时间。包括
syscall
的上下文切换时间还是线程之间的上下文切换时间?