- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在研究 C++ 内存序列,但它很困惑。
例如:
void sumUp(std::atomic<int>& sum, std::vector<int>& val)
{
int tmpSum = 0;
for(auto i = 0; i < 100; ++i) tmpSum += val[i];
sum.fetch_add(tmpSum, std::memory_order_relaxed);
}
我不明白 sum.fetch_add()
在 tmpSum += val[i]
之后运行。既然顺序不对,sum.fetch_add()
可以在tmpSum += val[i]
之前操作吗?
那么总和0可能吗?
非常感谢。
最佳答案
memory_order
在单个线程的上下文中没有可观察到的效果:
让我们看看(x
、a
和b
最初都是0
):
auto t1(std::atomic<int>& x, int& a, int& b)
{
a = 3; // 1
b = 5; // 2
x.store(a, std::memory_order_relaxed); // 3
}
因为 (1) 和 (2) 不相互依赖,编译器可以重新排序它们。例如。可以做 (1) -> (2) 或 (2) -> (1)
因为 (3) 取决于 (1)((1) 写入 a
并且 (3) 从 a
读取)编译器不能在 (3) 之前执行 ( 1).这与 (3) 中指定的内存顺序无关
因为 (3) 不依赖于 (2),通常在单线程模型中,编译器可以在 (2) 之前执行 (3)。
但由于 x
是原子的,请考虑另一个线程执行此操作(x
、a
和 b
是对与提供给 t1
的参数相同,并且最初都是 0
):
auto t2(std::atomic<int>& x, int& a, int& b)
{
while(x.load(std::memory_order_relaxed) == 3) // 4
assert(b == 5); // 5
}
此线程一直等到 x
为 3
,然后断言 b
为 5
。现在您可以看到在顺序单线程世界中 (2) 和 (3) 如何在没有任何可观察行为的情况下重新排序,但在多线程模型中,(2) 和 (3) 的顺序可能会对行为产生影响程序。
这就是 memory_order
的作用:它指定可以在原子之前或之后重新排序而对单个线程没有任何影响的操作是否可以这样重新排序。原因是它们可能会对多线程程序产生影响。编译器不知道这一点,只有程序员知道,因此需要额外的 memory_order
参数。
使用 memory_order_relaxed
断言可能会失败,因为 (2) 可能发生在 (3) 之后,但是使用 memory_order_seq_cst
(默认)断言永远不会失败,因为 (2)
发生在 (3) 之前。
回到您的示例,无论您指定什么 memory_order
,都可以保证 tmpSum += val[i];
发生在 sum 之前。 fetch_add(tmpSum, std::memory_order_relaxed);
因为第二个依赖于第一个。 memory_order
会影响不影响原子操作的指令的可能重新排序。例如。如果你有一个 int unrelated = 24
。
顺便说一句,官方术语是“sequenced before”和“sequenced after”
在现实世界中,硬件使事情变得有点复杂。操作可以在当前线程中以一种顺序出现,但另一个线程可以以另一种顺序看到它们,因此更严格的memory_order
必须采用额外的措施来确保跨线程的顺序一致.
严格来说,在这个例子中,如果使用 memory_order_relaxed
,我们会出现未定义行为,因为对 b
的访问不是跨线程同步的。
关于c++ - 了解内存序列和 std::memory_order_relaxed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52719079/
我开始在 Ethereum blockchain 上了解如何开发智能合约以及如何写 web-script用于与智能合约交互(购买、销售、统计......)我得出了该怎么做的结论。我想知道我是否正确理解
我正在 UIView 中使用 CATransform3DMakeRotation,并且我正在尝试进行 45º,变换就像向后放置一样: 这是我拥有的“代码”,但显然没有这样做。 CATransform3
我目前正在测试 WebRTC 的功能,但我有一些脑逻辑问题。 WebRTC 究竟是什么? 我只读了“STUN”、“P2P”和其他...但是在技术方面什么是正确的 WebRTC(见下一个) 我需要什么
我在看 DelayedInit在 Scala in Depth ... 注释是我对代码的理解。 下面的 trait 接受一个非严格计算的参数(由于 => ),并返回 Unit .它的行为类似于构造函数
谁能给我指出一个用图片和简单的代码片段解释 WCF 的资源。我厌倦了谷歌搜索并在所有搜索结果中找到相同的“ABC”文章。 最佳答案 WCF 是一项非常复杂的技术,在我看来,它的文档记录非常少。启动和运
我期待以下 GetArgs.hs打印出传递给它的参数。 import System.Environment main = do args main 3 4 3 :39:1: Coul
private int vbo; private int ibo; vbo = glGenBuffers(); ibo = glGenBuffers(); glBindBuffer(GL_ARRAY_
我正在尝试一个 for 循环。我添加了一个 if 语句以在循环达到 30 时停止循环。 我见过i <= 10将运行 11 次,因为循环在达到 10 次时仍会运行。 如果有设置 i 的 if 语句,为什
我正在尝试了解 WSGI 的功能并需要一些帮助。 到目前为止,我知道它是一种服务器和应用程序之间的中间件,用于将不同的应用程序框架(位于服务器端)与应用程序连接,前提是相关框架具有 WSGI 适配器。
我是 Javascript 的新手,我正在尝试绕过 while 循环。我了解它们的目的,我想我了解它们的工作原理,但我在使用它们时遇到了麻烦。 我希望 while 值自身重复,直到两个随机数相互匹配。
我刚刚偶然发现Fabric并且文档并没有真正说明它是如何工作的。 我有根据的猜测是您需要在客户端和服务器端都安装它。 Python 代码存储在客户端,并在命令运行时通过 Fabric 的有线协议(pr
我想了解 ConditionalWeakTable .和有什么区别 class ClassA { static readonly ConditionalWeakTable OtherClass
关闭。这个问题需要更多focused .它目前不接受答案。 想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post . 5年前关闭。 Improve this questi
我还没有成功找到任何可以引导我理解 UIPickerView 和 UIPickerView 模型的好例子。有什么建议吗? 最佳答案 为什么不使用默认的 Apple 文档示例?这是来自苹果文档的名为 U
我在看foldM为了获得关于如何使用它的直觉。 foldM :: Monad m => (a -> b -> m a) -> a -> [b] -> m a 在这个简单的例子中,我只返回 [Just
答案What are _mm_prefetch() locality hints?详细说明提示的含义。 我的问题是:我想要哪一个? 我正在处理一个被重复调用数十亿次的函数,其中包含一些 int 参数。
我一直在读这个article了解 gcroot 模板。我明白 gcroot provides handles into the garbage collected heap 然后 the handle
提供了一个用例: 流处理架构;事件进入 Kafka,然后由带有 MongoDB 接收器的作业进行处理。 数据库名称:myWebsite集合:用户 并且作业接收 users 集合中的 user 记录。
你好 我想更详细地了解 NFS 文件系统。我偶然发现了《NFS 图解》这本书,不幸的是它只能作为谷歌图书提供,所以有些页面丢失了。有人可能有另一个很好的资源,这将是在较低级别上了解 NFS 的良好开始
我无法理解这个问题,哪个更随机? rand() 或: rand() * rand() 我发现这是一个真正的脑筋急转弯,你能帮我吗? 编辑: 凭直觉,我知道数学答案是它们同样随机,但我忍不住认为,如果您
我是一名优秀的程序员,十分优秀!