_mm_pause在英特尔的gcc中使用

问题描述 投票:0回答:2

我已经提到过这个网页:qazxsw poi,以下我无法理解:

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

我想知道,Linux中的lscpu会显示cpu信息,但我不知道cpu我是否支持SSE2,我怎么能自己查看?!

https://software.intel.com/en-us/articles/benefitting-power-and-performance-sleep-loops

另外,目前我使用_mm_pause或__asm volatile(“pause”:::“memory”); cpu idle将在该核心中耗尽为零,但使用nanosleep的以下代码对我来说太慢了:

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

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

编辑:

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

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

linux x86 intel sleep pause
2个回答
5
投票

检查您的平台是否支持SSE2

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

但是你不需要检查支持:gcc -march=native -dM -E - </dev/null | grep SSE 安全地解码为不能识别为pause instruction的CPU上的NOP。 (编码基本上是pause)。 rep nop而不是管道中的5或100个循环暂停可能不是代码的正确性问题。


nop不会为调度程序释放CPU,因为你提到它是为另一个目的而设计的,例如:提示微架构组件。

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

- 编辑 -

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

此外,只需将CPU空闲几纳秒,实际上不会节省电量。 CPU功率由C状态或P状态保存。 P-State使用频率缩放,而C-State关闭CPU的组件。尽管存在可以执行此类状态转换的暂停指令,但是这需要时间(在我们的范围内的延迟)这使得它变得昂贵。

参考:

_mm_pause

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


0
投票

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

另外,请注意

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

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

© www.soinside.com 2019 - 2024. All rights reserved.