当前位置: 首页 > 面试题库 >

在Linux上相同进程的线程之间进行上下文切换的成本

邹博裕
2023-03-14
问题内容

是否有关于Linux上同一进程的线程之间进行上下文切换的成本的任何良好的经验数据(主要是x86和x86_64)?我说的是一个线程在用户空间中执行的最后一条指令在自愿或非自愿进入睡眠之前执行的最后一个指令之间的周期数或纳秒数,同一进程的另一个线程在同一CPU
/内核唤醒后执行的第一条指令之间的周期数或纳秒数。

我编写了一个快速测试程序,该程序rdtsc在分配给同一cpu /
core的2个线程中不断执行,将结果存储在volatile变量中,并与其姊妹线程的相应volatile变量进行比较。第一次检测到姊妹线程的值发生变化时,它会打印差异,然后返回循环。通过这种方式,我在Atom
D510 cpu上获得的最小/中位数约为8900/9600个周期。这个程序看起来合理吗,数字似乎可信吗?

我的目标是估计在现代系统上,每连接线程服务器模型是否可以与选择类型的多路复用竞争,甚至胜过选择类型的多路复用。从理论上讲这似乎是合理的,因为从在fd
X上执行IO到fd的转换Y仅涉及在一个线程中hibernate并在另一个线程中唤醒,而不是多个系统调用,但这取决于上下文切换的开销。


问题答案:

(免责声明:这不是对该问题的直接回答,只是一些建议,希望对您有所帮助)。

首先,您获得的数字肯定听起来像是在球场上。但是请注意,在实现相同ISA的不同CPU型号之间,中断/陷阱延迟可能会有 很大
差异。如果您的线程使用了浮点或向量运算,则情况也不同,因为如果没有,则内核会避免保存/恢复浮点或向量单元状态。

通过使用内核跟踪基础结构,您应该能够获得更准确的数字- perf sched特别是用于测量和分析调度程序延迟的设计。

如果您的目标是为每个连接线程服务器建模,那么您可能不应该测量非自愿的上下文切换延迟-
通常在这样的服务器中,大多数上下文切换将是自愿的,因为线程会阻塞read()等待更多数据来自网络。因此,更好的测试平台可能涉及测量从一个线程阻塞read()到另一个线程被唤醒的等待时间。

请注意,在写得很好的多路复用服务器上,如果负载很重,从fd X到fd
的转换Y通常会涉及相同的单个系统调用(因为服务器会迭代从单个返回的活动文件描述符列表epoll())。一个线程也应该比多个线程具有更少的缓存占用空间,只需通过只有一个堆栈即可。我怀疑解决此事的唯一方法(对于“和解”的某种定义)可能是进行基准枪战。



 类似资料:
  • 问题内容: 在阅读了这个答案和Robert Love的“LinuxKernelDevelopment”之后,随后在系统调用中,我发现Linux中的进程和线程(几乎)与内核没有区别。它们之间有一些调整(在引用的SO问题中被讨论为“更多共享”或“更少共享”),但是我仍然有一些问题需要解答。 我最近开发了一个包含几个POSIX线程的程序,并决定在此前提下进行试验。在创建两个线程的进程中,所有线程当然都会

  • 本文向大家介绍计算Linux上进程中的线程数,包括了计算Linux上进程中的线程数的使用技巧和注意事项,需要的朋友参考一下 Linux进程可以可视化为程序的运行实例,其中Linux中的每个线程不过是进程的执行流。您知道如何在Linux环境中查看每个进程的线程数吗?有几种计数线程数的方法。本文讨论如何读取有关Linux上进程的信息以及如何计算每个进程的线程数。 阅读过程信息 要读取过程信息,请使用“

  • 问题内容: 如何使用C语言在ubuntu linux机器上查找进程开始时间。在linux中,/ proc / [pid] / stat文件提供信息 和文件/ proc / stat给出 为了将这两个值相加,我如何将以前的值转换成秒,因为它是以jiffies为单位。 问题答案: 当人们编译Linux内核时,每秒Jiffies是可配置的。 以下程序使用您正在运行的内核上每秒的跳动次数。它带有一个可选的

  • 我的程序中运行了两个线程。当我尝试在非主线程中使用OpenGL函数时,它抛出了一个IllegalStateException:当前线程中没有当前的OpenGL上下文。所以我的问题是,如何将上下文从主线程传递到另一个线程?我正在使用LWJGL 3。

  • 请问下有用户栈和内核栈的那种系统调度模式在切换进程前必须先完成线程的切换吗?还是说可以直接从A进程切换到B进程

  • 本文向大家介绍进程和线程之间的区别,包括了进程和线程之间的区别的使用技巧和注意事项,需要的朋友参考一下 进程是活动程序,即正在执行的程序。它不仅包含程序代码,还包括程序计数器,进程堆栈,寄存器,程序代码等。与此相比,程序代码只是文本部分。 线程是可以由调度程序独立管理的轻量级进程。它使用并行性提高了应用程序性能。线程与它的对等线程共享信息,如数据段,代码段,文件等,而该线程包含其自己的寄存器,堆栈