6

我参考了这个网页: https ://software.intel.com/en-us/articles/benefit-power-and-performance-sleep-loops ,以下我看不懂:

暂停指令向处理器提示调用线程处于“自旋等待”循环中。此外,当在不支持英特尔 SSE2 的 x86 架构上使用时,暂停指令是无操作的,这意味着它仍然会在不执行任何操作或引发故障的情况下执行。虽然这意味着不支持英特尔 SSE2 的旧 x86 架构不会看到暂停带来的好处,但这也意味着您可以保留一个可以全面运行的简单代码路径。

我想知道,linux中的lscpu会显示cpu信息,但是我不知道我的cpu是否支持SSE2,我该如何自己检查?!

Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                24
On-line CPU(s) list:   0-23
Thread(s) per core:    2
Core(s) per socket:    6
Socket(s):             2
NUMA node(s):          2
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 63
Model name:            Intel(R) Xeon(R) CPU E5-2643 v3 @ 3.40GHz
Stepping:              2
CPU MHz:               3599.882
BogoMIPS:              6804.22
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              20480K
NUMA node0 CPU(s):     0,2,4,6,8,10,12,14,16,18,20,22
NUMA node1 CPU(s):     1,3,5,7,9,11,13,15,17,19,21,23

另外,目前我使用 _mm_pause 或 __asm volatile ("pause" ::: "memory"); 该内核中的 cpu 空闲将耗尽到零,但是使用 nanosleep 的以下代码对我来说太慢了:

while(1){
    nanosleep();
    dosomething..... ; 
}

我观察到 nanosleep 在我的盒子里会延迟 60 微秒,有没有比 nanosleep 更快的解决方案也不会像 _mm_pause() 或 __asm volatile ("pause" ::: "memory") 那样耗尽 cpu 核心?!

编辑 :

struct timespec req={0};
req.tv_sec=0;
req.tv_nsec=100 ;
nanosleep(&req,NULL) ;

这个 nanosleep 在我上面哪个 cpu 的盒子里花费了 60 微秒,我不知道它是怎么发生的?!

4

2 回答 2

8

检查您的平台是否支持 SSE2

gcc -march=native -dM -E - </dev/null | grep SSE

但是您不需要检查是否支持:pause指令在不将其识别为pause. (编码基本上是rep nop)。管道中的 5 或 100 个周期暂停不太nop可能是您的代码的正确性问题。


_mm_pause不会为 scheduler 释放 CPU,因为您提到它是为其他目的而设计的,例如微架构组件的提示。

nanosleep,如果使用得当,应该会给你比 *60us 更好的控制(你可能需要将调度程序更改为 RT)。我建议您检查您的代码以查看参数是否设置正确等。

- 编辑 -

nanosleep 函数的准确性取决于内核。它的短睡眠行为只是 glibc 中的忙循环(参见参考资料)。由于调度程序仅在定时器触发时切换上下文,因此也不可能在小于调度程序滴答(由 CONFIG_HZ 确定,通常为 250、1000 等)的间隔(例如,几纳秒)内向调度程序屈服。

此外,只是让 CPU 闲置几纳秒实际上不会节省电力。CPU 功率通过 C-State 或 P-State 来节省。P-State 使用频率缩放,而 C-State 关闭 CPU 的组件。尽管有停止指令可以进行这种状态转换,但是这样做需要时间(我们范围内的延迟),这使得它变得昂贵。

参考:

http://tldp.org/HOWTO/IO-Port-Programming-4.html

http://ena-hpc.org/2014/pdf/paper_06.pdf

于 2016-05-06T06:00:11.397 回答
0

我认为一个简单的解决方案(比 nanosleep 更快)是使用多个暂停指令。

另外,请注意

需要注意的是,暂停指令延迟的周期数可能因处理器系列而异。您应该避免使用多个暂停指令,假设您将引入特定周期计数的延迟。

在有益于电源和性能睡眠循环中提到

于 2019-05-16T02:31:57.447 回答