gpt4 book ai didi

windows - 如何理解acquire和release语义?

转载 作者:可可西里 更新时间:2023-11-01 13:54:39 31 4
gpt4 key购买 nike

我从 MSDN 中找到了三个函数,如下:

1.InterlockedDecrement().

2.InterlockedDecrementAcquire().

3.InterlockedDecrementRelease().

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

最佳答案

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

我会尝试一下。

需要记住的是,编译器或 CPU 本身可能会重新排序内存读写,如果它们似乎没有相互处理的话。

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

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,但可能需要更长的时间。

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

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

这就是 Acquire 和 Release 排序语义发挥作用的地方。我通过使用 Acquire 语义设置一个标志左右来设置我正在做的工作,并且 CPU 保证我在该指令之后玩的任何内存游戏实际上保持在该指令之下。我通过使用 Release 语义设置一个标志左右来设置我已经完成,并且 CPU 保证我在发布之前完成的任何内存游戏实际上保留在发布之前。

通常,人们会使用显式锁(互斥锁、信号量等)来执行此操作,其中 CPU 已经知道它必须注意内存排序。尝试创建“无锁”数据结构的目的是提供线程安全的数据结构(对于线程安全的某种含义),不使用显式锁(因为它们非常慢)。

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

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

关于windows - 如何理解acquire和release语义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24565540/

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