是否有关于Linux上同一进程的线程之间进行上下文切换的成本的任何良好的经验数据(主要是x86和x86_64)?我说的是一个线程在用户空间中执行的最后一条指令在自愿或非自愿进入睡眠之前执行的最后一个指令之间的周期数或纳秒数,同一进程的另一个线程在同一CPU /内核唤醒后执行的第一条指令之间的周期数或纳秒数。
我编写了一个快速测试程序,该程序rdtsc在分配给同一cpu / core的2个线程中不断执行,将结果存储在volatile变量中,并与其姊妹线程的相应volatile变量进行比较。第一次检测到姊妹线程的值发生变化时,它会打印差异,然后返回循环。通过这种方式,我在Atom D510 cpu上获得的最小/中位数约为8900/9600个周期。这个程序看起来合理吗,数字似乎可信吗?
rdtsc
我的目标是估计在现代系统上,每连接线程服务器模型是否可以与选择类型的多路复用竞争,甚至胜过选择类型的多路复用。从理论上讲这似乎是合理的,因为从在fd X上执行IO到fd的转换Y仅涉及在一个线程中hibernate并在另一个线程中唤醒,而不是多个系统调用,但这取决于上下文切换的开销。
X
Y
(免责声明:这不是对该问题的直接回答,只是一些建议,希望对您有所帮助)。
首先,您获得的数字肯定听起来像是在球场上。但是请注意,在实现相同ISA的不同CPU型号之间,中断/陷阱延迟可能会有 很大 差异。如果您的线程使用了浮点或向量运算,则情况也不同,因为如果没有,则内核会避免保存/恢复浮点或向量单元状态。
通过使用内核跟踪基础结构,您应该能够获得更准确的数字- perf sched特别是用于测量和分析调度程序延迟的设计。
perf sched
如果您的目标是为每个连接线程服务器建模,那么您可能不应该测量非自愿的上下文切换延迟- 通常在这样的服务器中,大多数上下文切换将是自愿的,因为线程会阻塞read()等待更多数据来自网络。因此,更好的测试平台可能涉及测量从一个线程阻塞read()到另一个线程被唤醒的等待时间。
read()
请注意,在写得很好的多路复用服务器上,如果负载很重,从fd X到fd 的转换Y通常会涉及相同的单个系统调用(因为服务器会迭代从单个返回的活动文件描述符列表epoll())。一个线程也应该比多个线程具有更少的缓存占用空间,只需通过只有一个堆栈即可。我怀疑解决此事的唯一方法(对于“和解”的某种定义)可能是进行基准枪战。
epoll()