标签: context-switch

无意识上下文切换的原因

我正在尝试描述一个多线程程序,我在一台大型机器(32核,256GB RAM)上编写.我注意到在运行之间,程序的性能可能会有很大差异(70-80%).我似乎无法找到程序性能中这种巨大差异的原因,但通过分析大量运行中"时间"效用的结果,我注意到非自愿上下文切换的数量与程序性能(显然,较少的上下文切换导致更好的性能,反之亦然).

有没有什么好方法可以确定导致此上下文切换的原因?如果我能发现罪魁祸首,那么也许我可以尝试解决问题.但是,我对可以使用的工具有一些特殊的限制.首先,我没有机器上的root权限,因此任何需要此类权限的工具都没有.其次,它是一个相当老的内核(RHEL5,内核2.6.18),因此可能不存在一些标准的perf事件.无论如何,任何关于如何更深入地了解这种情境转换的原因的建议将不胜感激.

更新:我决定在另一台(和更小的)机器上测试我的程序.另一台机器是一个带有8Gb RAM的4核(带有高速)linux盒子,另一台机器上有一个更新的内核--- 3.2.0和2.6.18.在新机器上,我无法重现双模式性能配置文件.这让我相信这个问题要么是因为硬件问题(如评论中所建议的),要么是内核级别的特定病态情况,这个问题已经得到修复.我目前最好的假设是,它可能是因为新机器具有完全公平调度程序(CFS)的内核而旧机器没有.有没有办法测试这个假设(告诉新机器使用不同的/旧的调度程序)而不必重新编译新机器的古老内核版本?

c++ performance multithreading profiling context-switch

11
推荐指数
2
解决办法
3084
查看次数

我的线程可以帮助操作系统决定何时将其切换出来吗?

我正在使用C++中的Linux上的线程应用程序,它试图实时,在心跳上执行操作,或尽可能接近它.

在实践中,我发现操作系统正在交换我的线程,并在切换时导致延迟达十分之一秒,导致心跳不规则.

有没有办法我的线程可以提示操作系统,现在是上下文切换它的好时机?我可以在做心跳之后立即进行此呼叫,从而最大限度地减少由于定时上下文切换导致的延迟.

c++ linux pthreads context-switch

10
推荐指数
1
解决办法
1022
查看次数

上下文切换有多贵?实现手动任务切换比依赖OS线程更好吗?

想象一下,我有两个(三个,四个,无论如何)任务必须并行运行.现在,执行此操作的简单方法是创建单独的线程并忘记它.但是在一个普通的单核CPU上意味着大量的上下文切换 - 而且我们都知道上下文切换是大的,坏的,慢的,通常只是邪恶的.应该避免,对吗?

在这方面,如果我从头开始编写软件,我可以加倍努力并实现我自己的任务切换.将每个任务拆分为部分,将状态保存在中间,然后在单个线程中切换它们.或者,如果我检测到有多个CPU核心,我可以将每个任务分配给一个单独的线程,一切都会很好.

第二种解决方案确实具有适应可用CPU核心数量的优势,但是手动任务切换真的会比OS核心更快吗?特别是如果我试图通过a TaskManager和a ITask等使整个事物变得通用?

澄清:我是Windows开发人员,所以我主要对这个操作系统的答案感兴趣,但最有趣的是找到其他操作系统.当您写下答案时,请说明它是哪个操作系统.

更多说明:好的,所以这不是在特定应用程序的上下文中.这是一个普遍的问题,是我对可扩展性的思考的结果.如果我希望我的应用程序可以扩展并有效地利用未来的CPU(甚至是今天的不同CPU),我必须使其成为多线程.但有多少线程?如果我创建一个固定数量的线程,那么程序将在所有没有相同内核数量的CPU上执行次优.

理想情况下,线程数将在运行时确定,但很少有可以在运行时真正分成任意数量的部分的任务.然而,许多任务可以在设计时分成相当大的恒定线程数.因此,例如,如果我的程序可以产生32个线程,那么它已经可以利用多达32核CPU的所有内核,这在未来还很遥远(我认为).但是在一个简单的单核或双核CPU上,它意味着很多上下文切换,这会减慢速度.

因此我对手动任务切换的想法.这样就可以制作32个"虚拟"线程,这些线程将被映射到最佳的真实线程,并且"上下文切换"将手动完成.问题是 - 我的手动"上下文切换"的开销是否会低于OS上下文切换的开销?

当然,所有这些都适用于受CPU限制的进程,如游戏.对于普通的CRUD应用程序,这几乎没有价值.这样的应用程序最好用一个线程(最多两个).

performance context-switch

9
推荐指数
2
解决办法
7626
查看次数

使用Zend Action Helper ContextSwitch创建自定义JSON响应对象

我通常会将一个编码的json对象附加到响应主体,但是我现在有一种情况需要使用ContextSwitch动作帮助器.

我有一个Zend_Form需要三个不同的响应上下文:

  1. html - 在布局中将表单渲染为普通html.
  2. html-partial - 一个ajax"get"请求,只将表单呈现为html.
  3. json - 一个返回任何表单valiation错误消息的ajax"post"请求.

对于每个上下文,我有3个视图脚本.虽然两个html上下文可以使用相同的视图脚本,但我还没弄清楚这是否可行.

  • form.phtml
  • form.html.phtml
  • form.json.phtml

html上下文视图工作正常,但json视图没有被选中.覆盖默认json post回调行为或将自定义编码对象传递给响应主体的最佳方法是什么?

php json zend-framework helper context-switch

9
推荐指数
1
解决办法
5646
查看次数

是否保证在每次切换进程时调用kernel/sched.c/context_switch()?

我想改变Linux内核,以便每当当前PID改变时 - 即,切换新进程 - 执行一些诊断代码(下面的详细解释,如果好奇的话).我做了一些挖掘工作,似乎每次调度程序选择一个新进程时,context_switch()都会调用该函数,这是有道理的(这只是粗略的分析sched.c/schedule()).

问题是,Linux调度程序现在对我来说基本上是黑魔法,所以我想知道这个假设是否正确.是否保证每次选择新进程以在CPU上获得一些时间时,都会调用context_switch()函数?或者内核源中是否有其他位置可以在其他情况下处理调度?(或者我完全误解了这一切?)

为了给出一些背景信息,我正在使用MARSS x86模拟器来尝试对某些程序进行一些检测和测量.问题是我的仪器需要知道某些代码事件对应于哪个执行过程,以避免误解数据.我们的想法是在MARSS中使用一些内置的消息传递系统在每个上下文切换时传递新进程的PID,因此它总是知道当前正在执行什么PID.如果有人能想到一种更简单的方法来实现这一点,那也将非常感激.

c linux process scheduler context-switch

9
推荐指数
1
解决办法
601
查看次数

MultiCore CPU,多线程和上下文切换?

假设我们有一个具有20个内核的CPU和一个具有20个CPU密集型的进程,彼此独立于每个线程:每个CPU内核一个线程.我试图弄清楚在这种情况下是否发生了上下文切换.我相信这是因为操作系统中的系统进程也需要CPU时间.

我知道有不同的CPU架构,一些答案可能会有所不同,但请您解释一下:

  • 如何在Linux或Windows以及一些已知的CPU架构上进行上下文切换?在现代硬件的引擎盖下会发生什么?
  • 如果我们有10个核心和20个线程或者反过来怎么办?
  • 如果我们有n个CPU,如何计算我们需要多少线程?
  • 上下文切换后CPU缓存(L1/L2)是否为空?

谢谢

cpu multithreading multiprocessing context-switch

9
推荐指数
1
解决办法
4327
查看次数

什么是用于的内核堆栈?

以下是我读过进程A和进程B之间的上下文切换的描述.我不明白内核堆栈的用途.假设是每进程内核堆栈.我正在阅读的描述说明了将A的寄存器保存到A的内核堆栈中,并将A的寄存器保存到A的进程结构中.将寄存器保存到内核堆栈和进程结构的重点是什么?为什么需要两者?

上下文切换在概念上很简单:所有操作系统必须做的是为当前正在执行的进程保存一些寄存器值(例如,在其内核堆栈上),并为即将执行的进程恢复一些(来自它的内核堆栈).通过这样做,OS因此确保当最终执行从陷阱返回指令时,系统不再返回到正在运行的进程,而是继续执行另一个进程...

进程A正在运行,然后被定时器中断中断.硬件将其寄存器(在其内核堆栈上)保存并进入内核(切换到内核模式).在定时器中断处理程序中,操作系统决定从正在运行的进程A切换到进程B.此时,它调用switch()例程,小心地保存当前寄存器值(进入A的进程结构),恢复寄存器进程B(来自其进程结构条目),然后切换上下文,特别是通过更改堆栈指针以使用B的内核堆栈(而不是A的).最后,OS从陷阱返回,它恢复B的寄存器并开始运行它.

stack operating-system kernel process context-switch

9
推荐指数
1
解决办法
4627
查看次数

在线程中调用'yield'有什么好的用例?

许多支持多线程的语言都提供了一个允许线程向其他线程提供上下文切换的操作.例如Haskell的yield.

但是,文档没有说明实际用例是什么.什么时候适合使用这些屈服函数,何时不适用?

最近我看到一个这样的用例再次提高Warp的性能,结果发现当网络服务器发送消息时,yield在尝试再次接收数据之前值得调用,因为它需要客户端一些时间来处理答案并发出另一个请求.

我想在调用时看到其他示例或指南yield带来一些好处.

我主要对Haskell感兴趣,但我不介意学习其他语言或概念.

注意:这与生成器或协同程序无关,例如yieldPython或Ruby.

multithreading haskell context-switch

8
推荐指数
1
解决办法
181
查看次数

调度程序和调度程序在进程调度的上下文中有什么区别

我目前正在攻读操作系统的本科课程.我对调度程序和调度程序在进程调度中的功​​能感到有些困惑.基于我所学到的,中期调度程序选择交换和输入的过程,并且一旦选择了过程,实际的交换操作由Dispatcher通过上下文切换执行.此外,短期调度程序负责根据所遵循的调度算法调度进程并为它们分配CPU时间.如果我错了,请纠正我.我对中期调度程序与调度程序的功能以及交换和上下文切换之间的差异感到困惑.

operating-system process scheduler context-switch

8
推荐指数
1
解决办法
9959
查看次数

在多核上下文切换期间是否刷新了处理器缓存?

最近讨论了Java Actors demo中seq处为什么有一个volatile标记

@volatile private var seq = 0L
private def nextSeq: Long = {
  val next = seq
  seq += 1
  next
}
Run Code Online (Sandbox Code Playgroud)

一个答案是线程可以迁移并且变量会丢失(其他内核的私有缓存中会有不一致的值)。但是,您通常不会标记每个变量volatile以启用多核执行。因此,无论何时切换上下文,内核都必须刷新缓存。但是,我找不到在任何地方明确发音的这句话。每个人,例如。维基百科,只关心寄存器和栈内存

进程的状态包括进程可能使用的所有寄存器,尤其是程序计数器,以及可能需要的任何其他操作系统特定数据。此数据通常存储在称为过程控制块 (PCB) 或开关帧的数据结构中。为了切换工艺,必须创建并保存第一个工艺的 PCB。PCB 有时存储在内核内存中的每个进程堆栈上(与用户模式调用堆栈相反),或者可能有一些特定的操作系统定义的数据结构用于此信息。

关于迁移通用数据/变量,我们实际上有什么?

caching multicore flush volatile context-switch

8
推荐指数
1
解决办法
2866
查看次数