CPU休息指令和C ++ 11原语 [英] CPU Relax instruction and C++11 primitives

查看:227
本文介绍了CPU休息指令和C ++ 11原语的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到,许多无锁算法使用特定于操作系统的原语实现,例如此处(其中使用Linux特定的原子原语)经常使用cpu relax指令。使用GCC,可以通过以下方式实现:

I've noticed that many lockless algorithms implemented using OS-specific primitives, such as the spin locks described here (which use Linux-specific atomic primitives) often make use of a "cpu relax" instruction. With GCC, this can be achieved with:

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

具体来说,此指令通常用于

Specifically, this instruction is often used in the body of while loop spin locks, while waiting for a variable to set to a certain value.

C ++ 11似乎并没有提供任何类型的可移植的 cpu_relax类型的指令。有什么原因吗?

C++11 doesn't seem to provide any kind of portable "cpu_relax" type instruction. Is there some reason for this? And does the "pause" statement actually accomplish anything useful?

编辑

另外,我会问:为什么C ++ 11标准委员会不会决定包括一个通用的 std :: cpu_relax()或者什么?

Also, I'd ask: why did the C++11 standards committee not decide to include a generic std::cpu_relax() or whatever? Is it too difficult to guarantee portability?

推荐答案

PAUSE 指令是x86具体。 唯一使用在自旋锁等待循环中,其中:

The PAUSE instruction is x86 specific. It's sole use is in spin-lock wait loops, where it:


提高自旋等待循环。当执行自旋等待循环时,处理器在退出循环时将遭受严重的性能损失,因为它检测到可能的存储器顺序违反。 PAUSE指令向处理器提示代码序列是自旋等待循环。

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.

另外:


在spinwait循环中插入暂停指令会大大降低处理器的功耗。

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

你把这条指令放在自旋锁循环中也是x86_64具体的。我不能说C ++ 11标准的民间,但我认为这是合理的,他们得出结论,这个魔术的正确的地方在相关的图书馆...以及所有其他魔法需要实现原子,互斥等

Where you put this instruction in a spin-lock loop is also x86_64 specific. I cannot speak for the C++11 standards folk, but I think it is reasonable for them to conclude that the right place for this magic is in the relevant library... along with all the other magic required to implement atomics, mutexes etc.

注意: PAUSE 执行处理器允许另一个线程运行。 是低级 pthread_yield()。 (虽然在Intel超线程内核上,但是它阻止了自旋锁线程占用内核。) PAUSE 的基本功能似乎是关闭通常的指令执行优化和流水线,这使线程减速(一点),但是已经发现锁很忙,这降低了触摸锁变量的速率,使得高速缓存系统在当前所有者处不被服务器敲击

NB: the PAUSE does not release the processor to allow another thread to run. It is not a "low-level" pthread_yield(). (Although on Intel Hyperthreaded cores, it does prevent the spin-lock thread from hogging the core.) The essential function of the PAUSE appears to be to turn off the usual instruction execution optimisations and pipelining, which slows the thread down (a bit), but having discovered the lock is busy, this reduces the rate at which the lock variable is touched, so that the cache system is not being pounded by the waiter while the current owner of the lock is trying to get on with real work.

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

Note that the primitives being used to "hand roll" spin-locks, mutexes etc. are not OS specific, but processor-specific.

我不确定我会将手动滚动自旋锁描述为无锁!

I'm not sure I would describe a "hand rolled" spin-lock as "lockless" !

FWIW,英特尔针对自旋锁(<64>英特尔®64和IA-32架构优化参考手册)的建议是:

FWIW, the Intel recommendation for a spin-lock ("Intel® 64 and IA-32 Architectures Optimization Reference Manual") is:

  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(),在我的机器上是:

Clearly one can write something which compiles to this, using a std::atomic_flag... or use pthread_spin_lock(), which on my machine is:

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

这很难过错,真的。

这篇关于CPU休息指令和C ++ 11原语的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆