如何理解获取和释放语义? [英] How to understand acquire and release semantics?

查看:31
本文介绍了如何理解获取和释放语义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从 MSDN 中发现了三个函数,如下:

I found out three function from MSDN , below:

1.InterlockedDecrement().

2.InterlockedDecrementAcquire().

3.InterlockedDecrementRelease().

我知道那些函数用于将值递减作为原子操作,但我不知道这三个函数之间的区别

I knew those fucntion use to decrement a value as an atomic operation, but i don't know distinction between the three function

推荐答案

(嗯……但不要问我这到底是什么意思)

(um... but don't ask me what does it mean exactly)

我会尝试一下.

需要记住的是,编译器或 CPU 本身可能会重新排序内存读取和写入,如果它们看起来不相互处理.

Something to remember is that the compiler, or the CPU itself, may reorder memory reads and writes if they appear to not deal with each other.

这很有用,例如,如果您有一些可能正在更新结构的代码:

This is useful, for instance, if you have some code that, maybe is updating a structure:

if ( playerMoved ) {
  playerPos.X += dx;
  playerPos.Y += dy; 

  // Keep the player above the world's surface.
  if ( playerPos.Z + dz > 0 ) {
     playerPos.Z += dz;
  }
  else {
     playerPos.Z = 0;
  }
}

上述大多数语句可能会重新排序,因为它们之间没有数据依赖关系,事实上,超标量 CPU 可能会同时执行大部分语句,或者可能会更早开始处理 Z 部分,因为它不会影响 X或 Y,但可能需要更长时间.

Most of above statements may be reordered because there's no data dependency between them, in fact, a superscalar CPU may execute most of those statements simultaneously, or maybe would start working on the Z section sooner, since it doesn't affect X or Y, but might take longer.

这就是问题所在 - 假设您正在尝试无锁编程.你想执行一大堆内存写入,也许,填充一个共享队列.您通过最终写入标志来表示您已完成.

Here's the problem with that - lets say that you're attempting lock-free programming. You want to perform a whole bunch of memory writes to, maybe, fill in a shared queue. You signal that you're done by finally writing to a flag.

好吧,由于该标志似乎与正在完成的其余工作无关,编译器和 CPU 可能会对这些指令重新排序,现在您可以在实际提交之前设置完成"标志其余结构内存,现在您的无锁"队列不起作用.

Well, since that flag appears to have nothing to do with the rest of the work being done, the compiler and the CPU may reorder those instructions, and now you may set your 'done' flag before you've actually committed the rest of the structure to memory, and now your "lock-free" queue doesn't work.

这是获取和释放排序语义发挥作用的地方.我通过设置一个带有 Acquire 语义的标志来设置我正在工作,并且 CPU 保证我在该指令之后玩的任何内存游戏实际上都低于该指令.我通过设置一个带有 Release 语义的标志来设置我已经完成,并且 CPU 保证我在发布之前完成的任何内存游戏实际上保留在发布之前.

This is where Acquire and Release ordering semantics come into play. I set that I'm doing work by setting a flag or so with an Acquire semantic, and the CPU guarantees that any memory games I play after that instruction stay actually below that instruction. I set that I'm done by setting a flag or so with a Release semantic, and the CPU guarantees that any memory games I had done just before the release actually stay before the release.

通常,人们会使用显式锁来做到这一点 - 互斥锁、信号量等,其中 CPU 已经知道它必须注意内存排序.尝试创建无锁"数据结构的重点是提供线程安全的数据结构(对于线程安全的某些含义),不使用显式锁(因为它们非常慢).

Normally, one would do this using explicit locks - mutexes, semaphores, etc, in which the CPU already knows it has to pay attention to memory ordering. The point of attempting to create 'lock free' data structures is to provide data structures that are thread safe (for some meaning of thread safe), that don't use explicit locks (because they are very slow).

在不支持获取/释放排序语义的 CPU 或编译器上创建无锁数据结构是可能的,但这通常意味着使用一些较慢的内存排序语义.例如,你可以发出一个完整的内存屏障——在这条指令之前的所有东西都必须在这条指令之前实际提交,而在这条指令之后的所有东西都必须在这条指令之后实际提交.但这可能意味着我在等待指令流(可能是函数调用序言)早期的一堆实际上不相关的内存写入,这与我试图实现的内存安全无关.

Creating lock-free data structures is possible on a CPU or compiler that doesn't support acquire/release ordering semantics, but it usually means that some slower memory ordering semantic is used. For instance, you could issue a full memory barrier - everything that came before this instruction has to actually be committed before this instruction, and everything that came after this instruction has to be committed actually after this instruction. But that might mean that I wait for a bunch of actually irrelevant memory writes from earlier in the instruction stream (perhaps function call prologue) that has nothing to do with the memory safety I'm trying to implement.

Acquire 说只担心我之后的事情".发布说只担心我之前的事情".将这两者结合起来就是一个完整的内存屏障.

Acquire says "only worry about stuff after me". Release says "only worry about stuff before me". Combining those both is a full memory barrier.

这篇关于如何理解获取和释放语义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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