gpt4 book ai didi

c++ - CPU 松弛指令和 C++11 原语

转载 作者:IT老高 更新时间:2023-10-28 22:35:17 30 4
gpt4 key购买 nike

我注意到许多无锁算法使用特定于操作系统的原语实现,例如描述的自旋锁here (使用 Linux 特定的原子原语)经常使用“cpu 放松”指令。使用 GCC,可以通过以下方式实现:

asm volatile("pause\n": : :"memory");

具体来说,该指令常用于while循环自旋锁的主体中,同时等待变量设置为某个值。

C++11 似乎没有提供任何可移植的“cpu_relax”类型指令。这有什么原因吗? “暂停”语句真的有什么用处吗?

编辑:

另外,我想问:为什么 C++11 标准委员会不决定包含一个通用的 std::cpu_relax() 或其他什么?便携性是不是太难保证了?

最佳答案

PAUSE指令是特定于 x86 的。它的唯一用途是在自旋锁等待循环中,它:

Improves the performance of spin-wait loops. When executing a “spin-wait loop,” processors will suffer a severe performance penalty when exiting the loop because it detects a possible memory order violation. The PAUSE instruction provides a hint to the processor that the code sequence is a spin-wait loop.

还有:

Inserting a pause instruction in a spinwait loop greatly reduces the processor’s power consumption.

将此指令放在自旋锁循环中的位置也是 x86_64 特定的。我不能代表 C++11 标准人员,但我认为他们有理由得出结论,这种魔法的正确位置是在相关库中......以及实现原子、互斥锁等所需的所有其他魔法.

注意: PAUSE 释放处理器以允许另一个线程运行。它不是“低级”pthread_yield() . (尽管在 Intel 超线程内核上,它确实可以防止自旋锁线程占用内核。)PAUSE 的基本功能似乎是关闭通常的指令执行优化和流水线,这会减慢线程(有点),但是发现锁很忙,这降低了锁变量被触摸的速率,因此缓存系统是当锁的当前所有者试图继续实际工作时,不会被服务员敲打。

请注意,用于“手动滚动”自旋锁、互斥锁等的原语不是特定于操作系统的,而是特定于处理器的。

我不确定我是否会将“手卷”自旋锁描述为“无锁”!

FWIW,英特尔对自旋锁的建议(“英特尔® 64 和 IA-32 架构优化引用手册”)是:

  Spin_Lock:
CMP lockvar, 0 // Check if lock is free.
JE Get_lock
PAUSE // Short delay.
JMP Spin_Lock
Get_Lock:
MOV EAX, 1
XCHG EAX, lockvar // Try to get lock.
CMP EAX, 0 // Test if successful.
JNE Spin_Lock

很明显,可以使用 std::atomic_flag 编写一些可以编译的东西。 ... 或使用 pthread_spin_lock() ,在我的机器上是:

  pthread_spin_lock:
lock decl (%rdi)
jne wait
xor %eax, %eax
ret
wait:
pause
cmpl $0, (%rdi)
jg pthread_spin_lock
jmp wait

这很难出错,真的。

关于c++ - CPU 松弛指令和 C++11 原语,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25189839/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com