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