_mm_pause 在 Intel 上的 gcc 中的用法
_mm_pause usage in gcc on Intel
我参考了这个网页:
https://software.intel.com/en-us/articles/benefitting-power-and-performance-sleep-loops ,以下我无法理解:
the pause instruction gives a hint to the processor that the calling thread is in a "spin-wait" loop. In addition, the pause instruction is a no-op when used on x86 architectures that do not support Intel SSE2, meaning it will still execute without doing anything or raising a fault. While this means older x86 architectures that don’t support Intel SSE2 won’t see the benefits of the pause, it also means that you can keep one straightforward code path that works across the board.
我想知道,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 idle 将在该核心中耗尽为零,但以下使用 nanosleep 的代码对我来说太慢了:
while(1){
nanosleep();
dosomething..... ;
}
我观察到 nanosleep 在我的盒子里会延迟 60 微秒,有没有比 nanosleep 更快的解决方案也不会像 _mm_pause() 或 __asm volatile ("pause" ::: "memory") ?!
编辑:
struct timespec req={0};
req.tv_sec=0;
req.tv_nsec=100 ;
nanosleep(&req,NULL) ;
这个 nanosleep 在我上面 cpu 的盒子里花费了 60 微秒,
我不知道怎么会这样?!
检查您的平台是否支持 SSE2
gcc -march=native -dM -E - </dev/null | grep SSE
但您不需要检查支持:pause
instruction 安全地解码为 CPU 上的 NOP,但不会将其识别为 pause
.(编码基本就是rep nop
)。管道中的 nop
而不是 5 或 100 周期暂停不太可能是代码的正确性问题。
_mm_pause
不会为 scheduler 发布 CPU,因为你提到它是为其他目的而设计的,例如微体系结构组件的提示。
nanosleep,如果使用得当,应该比 *60us 给你更好的控制(你可能需要将调度程序更改为 RT)。我建议你检查你的代码,看看是否正确设置了参数等。
--编辑--
nanosleep 函数的准确性取决于内核。它的短暂睡眠行为只是 glibc 中的忙循环(参见参考资料)。也不可能在小于调度程序滴答声(由 CONFIG_HZ 确定,通常为 250、1000 等)的时间间隔(例如几纳秒)内屈服于调度程序,因为调度程序仅在计时器触发时进行上下文切换.
此外,只是让 CPU 闲置几纳秒实际上并不能节省电量。 CPU 通过 C 状态或 P 状态来节省功率。 P-State 使用频率缩放,而 C-State 关闭 CPU 的组件。虽然有暂停指令可以进行这种状态转换,但这样做需要时间(我们范围内的延迟),这使得它变得昂贵。
参考:
我认为一个简单的解决方案(比 nanosleep 更快)是使用多个暂停指令。
此外,请注意
It is important to note that the number of cycles delayed by the pause
instruction may vary from one processor family to another. You should
avoid using multiple pause instructions, assuming you will introduce a
delay of a specific cycle count.
我参考了这个网页: https://software.intel.com/en-us/articles/benefitting-power-and-performance-sleep-loops ,以下我无法理解:
the pause instruction gives a hint to the processor that the calling thread is in a "spin-wait" loop. In addition, the pause instruction is a no-op when used on x86 architectures that do not support Intel SSE2, meaning it will still execute without doing anything or raising a fault. While this means older x86 architectures that don’t support Intel SSE2 won’t see the benefits of the pause, it also means that you can keep one straightforward code path that works across the board.
我想知道,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 idle 将在该核心中耗尽为零,但以下使用 nanosleep 的代码对我来说太慢了:
while(1){
nanosleep();
dosomething..... ;
}
我观察到 nanosleep 在我的盒子里会延迟 60 微秒,有没有比 nanosleep 更快的解决方案也不会像 _mm_pause() 或 __asm volatile ("pause" ::: "memory") ?!
编辑:
struct timespec req={0};
req.tv_sec=0;
req.tv_nsec=100 ;
nanosleep(&req,NULL) ;
这个 nanosleep 在我上面 cpu 的盒子里花费了 60 微秒, 我不知道怎么会这样?!
检查您的平台是否支持 SSE2
gcc -march=native -dM -E - </dev/null | grep SSE
但您不需要检查支持:pause
instruction 安全地解码为 CPU 上的 NOP,但不会将其识别为 pause
.(编码基本就是rep nop
)。管道中的 nop
而不是 5 或 100 周期暂停不太可能是代码的正确性问题。
_mm_pause
不会为 scheduler 发布 CPU,因为你提到它是为其他目的而设计的,例如微体系结构组件的提示。
nanosleep,如果使用得当,应该比 *60us 给你更好的控制(你可能需要将调度程序更改为 RT)。我建议你检查你的代码,看看是否正确设置了参数等。
--编辑--
nanosleep 函数的准确性取决于内核。它的短暂睡眠行为只是 glibc 中的忙循环(参见参考资料)。也不可能在小于调度程序滴答声(由 CONFIG_HZ 确定,通常为 250、1000 等)的时间间隔(例如几纳秒)内屈服于调度程序,因为调度程序仅在计时器触发时进行上下文切换.
此外,只是让 CPU 闲置几纳秒实际上并不能节省电量。 CPU 通过 C 状态或 P 状态来节省功率。 P-State 使用频率缩放,而 C-State 关闭 CPU 的组件。虽然有暂停指令可以进行这种状态转换,但这样做需要时间(我们范围内的延迟),这使得它变得昂贵。
参考:
我认为一个简单的解决方案(比 nanosleep 更快)是使用多个暂停指令。
此外,请注意
It is important to note that the number of cycles delayed by the pause instruction may vary from one processor family to another. You should avoid using multiple pause instructions, assuming you will introduce a delay of a specific cycle count.