在调试时,单个线程应用程序会在核心之间跳转吗?

时间:2013-12-16 10:03:13

标签: c linux gdb eclipse-cdt u-boot

我正在尝试使用Eclipse CDT调试多架构OSS程序(沙箱配置下的Das u-boot启动加载程序 - 它生成标准的linux可执行文件)。我喜欢它呈现的东西(精彩的GUI工作!)。例如,它为线程显示了类似的内容,

Thread [1] 9480 [core:2] (Suspend:Step)

当我运行程序时,“核心编号”会改变(在英特尔i3上运行时,值在0和3之间)。这最初使我相信调试器向我展示了应用程序的不同处理上下文(即我认为它在所有4个处理器内核上运行)。我花了很多时间尝试安装“多核gbd调试器”并进行配置,但不得不承认最终失败。

当我在一个周末后回到问题时,我注意到虽然“核心号码”会改变,但是线程ID没有(另外,我找不到(在源代码中){{1} (或类似的)系统调用来自)。

我目前的理论是该程序确实作为单线程应用程序运行,但由于我不理解的原因,喜欢在我的系统的不同处理器核心之间跳转。

我的问题如下;

  1. 我现在的理论是否正确?
  2. 如果是这样,我可以期待在调试环境之外运行的fork()单线程应用程序的这种行为吗?
  3. 从优化的角度来看,在核心之间移动时会有一些上下文切换,即使对于单线程应用程序也是如此。跳楼有什么实际好处吗?

1 个答案:

答案 0 :(得分:6)

  1. 取决于。
  2. 正在发生的事情是调度程序选择最好的CPU(让我们将其定义为:物理cpu,核心,超线程中的任何一个),以便根据许多变量运行进程。通常,调度程序将尝试将进程保留在同一CPU上以避免CPU之间的昂贵缓存和TLB丢失,但它必须在将进程移动到之前未运行的CPU的成本与之间进行权衡。等待以前的CPU可用的成本。

    假设您的进程X在CPU 0上运行。由于某些原因(等待锁定或I / O或抢占,因为它使用了太多的CPU和其他一些进程需要运行),它变得不可运行。另一个进程Y开始在CPU 0上运行。由于某种原因,您的进程X再次变为可运行。 CPU 1空闲。现在调度程序可以做出四个可能的决定:

    1. 等待进程Y完成运行,然后在CPU 0上运行进程X.
    2. 抢占进程Y,在CPU 0上运行进程X,将进程Y移动到CPU 1。
    3. 抢占进程Y,在CPU 0上运行进程X直到它停止运行,在CPU 0上恢复进程Y.
    4. 在CPU 1上运行进程X.
    5. 不同操作系统中的不同调度程序将做出不同的决策。有些人更喜欢所有进程的低延迟,而不考虑切换到不同CPU的成本,因此他们总是选择4.有些人更喜欢强亲和力,因此他们会选择1.在许多情况下,调度程序会对有多少缓存做出有根据的猜测状态进程X已经离开CPU 0并决定由于进程暂停了一段时间,它可能没有在CPU 0上留下那么多的缓存/ TLB,并且将它移动到它并不需要花费那么多一个不同的CPU。许多人会考虑内存总线布局并计算移动过程的成本,在您的情况下,调度程序可能知道移动的成本很低。调度程序也可以尽最大努力猜测进程Y的行为方式,如果它可能很快就完成运行,它可能会等待它完成。等

      通常情况下,除非你正在做一些真正需要从你的应用程序中挤出最后一纳秒性能的东西,否则你不必担心它。调度程序将做出足够好的决定,如果不是,那么无论如何对大多数应用程序来说都没那么重要。就大多数情况下你需要知道的那样,你的进程在每个指令之间的某个位置之间移动,而且永远都不会。