【问题标题】:Minimum time a thread can pause in LinuxLinux 中线程可以暂停的最短时间
【发布时间】:2011-09-10 13:03:41
【问题描述】:

在我的应用程序中,线程需要暂停很短的时间(100 秒的时钟周期)。暂停的一种方法是调用 nanosleep,但我想它需要对内核进行系统调用。现在我想暂停而不进入内核。

请注意,我有足够的内核来运行我的线程,并且我将每个线程绑定到一个单独的内核,因此即使是可以暂停内核一段时间的指令也会很好。我正在使用 x86。我只是想让线程在暂停时停止。我不想要一个繁忙的循环或对内核的系统调用。是否有可能做到这一点?我可以暂停线程的最短时间是多少?

【问题讨论】:

标签: c linux multithreading multicore


【解决方案1】:

_mm_pause 在忙等待循环中是要走的路。

不幸的是,它提供的延迟可能会随每个处理器系列而变化:

http://siyobik.info/main/reference/instruction/PAUSE

GCC 在 Linux 上的使用示例:

#include <xmmintrin.h>

int main (void) {
    _mm_pause();
    return 0;
}

在启用 MMX 的情况下编译:

gcc -o moo moo.c  -march=native

你也可以只使用内联汇编器:

__asm volatile ("pause" ::: "memory");

从一些英特尔工程师那里,您可能会发现这有助于确定暂停成本:

NOP 指令可以在 0.4-0.5 个时钟和 PAUSE 指令之间 可以消耗 38-40 个时钟。

http://software.intel.com/en-us/forums/showthread.php?t=48371

【讨论】:

  • 如何在gcc中使用_mm_pause?需要哪个头文件?
  • Steve-o,谢谢,但是 ::: "memory" 的目的是什么?是记忆栅栏还是什么?如果是这样,它不会增加缓存一致性负载吗?
  • @MetallicPriest 是为了确保暂停运行在正确的位置。
  • nop 不会停止乱序执行,甚至不需要任何后端执行资源。 nop 自 Core2(Atom 除外)以来,所有时钟的吞吐量为 4。 agner.org/optimize。无论如何,nop 不会像add 那样“占用周期”,它会消耗前端带宽和指令缓存空间。 无论如何,Sandybridge-family 上的pause 距离 Skylake 大约有 5 个周期,那里大约有 100 个周期。你的号码是 Pentium4 还是什么的?
【解决方案2】:

你为什么不自己旋转等待?您可以在一个循环中重复调用 rdtsc 指令以获取时钟周期计数,然后如果差值超过 100 个时钟周期就停止。

我认为这是用于交易系统,这是一种常见的技术

【讨论】:

  • rdtsc 消耗周期,这是我不想要的。我只想停止一个核心。
  • @MetallicPriest 如果你有足够多的核心,可以将线程绑定到每个核心而不会重叠,为什么要停止核心?
  • 呸,别再对缓存一致性等施加压力了。
【解决方案3】:

这取决于您所说的暂停是什么意思。如果您想通过暂停短时间停止线程,则只有操作系统可以执行此操作。

但是,如果您希望通过暂停进行非常短的延迟,则可以使用繁忙循环来执行此操作。使用这样一个循环的问题是你不知道它真正运行了多长时间。您可以估计它,但中断会使它变长。

【讨论】:

    【解决方案4】:

    一般来说,对于这么短的延迟,我认为系统调用是不切实际的,因为系统调用 + 调度 + 上下文切换并再次返回的开销将比你的暂停时间长得多,正如你似乎已经知道了。

    剩下的就是旋转(忙等待)来产生延迟。您可以循环读取 TSC 值以了解旋转量,例如(或适用于其他处理器的循环计数器寄存器)

    是的,像这样旋转确实会浪费能量,如果您在具有多个硬件线程的 CPU 上运行,正如多核通常暗示的那样,您还不必要地从其他线程中获取执行槽,但除非您有一个非常非常非常低开销的系统调用和调度程序机制以及高分辨率计时器,我会说这是不可能的。

    【讨论】:

      【解决方案5】:

      不 - 这是不可能的。调用sleepselect - 内核;或者有一个循环浪费时间。

      【讨论】:

        【解决方案6】:

        我认为,获得精确计时的唯一希望是使用timer_create 并通过信号传递计时器到期时间。实时调度。

        不过,我不确定它有什么用处,因为您无法在如此小的时间窗口内执行任何 IO,因此您的代码是否运行 1000 次且每次运行之间有 100ns 的间隔无关紧要, 或 1000 次,最后有 100 毫秒的间隙。

        【讨论】:

        • 不,我负担不起那么多开销!
        • 你想达到什么目的?你能在这么短的时间内做什么有用的事情取决于它发生的时间?
        • 它用于特定目的。我想暂停的原因是因为我不想对缓存一致性等施加压力。
        猜你喜欢
        • 1970-01-01
        • 2012-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-13
        • 1970-01-01
        • 2011-08-08
        • 1970-01-01
        相关资源
        最近更新 更多