gpt4 book ai didi

c++ - 为什么逻辑 AND/OR 的左操作数不依赖于父评估?

转载 作者:行者123 更新时间:2023-12-05 02:43:19 25 4
gpt4 key购买 nike

根据C++标准:

An evaluation A carries a dependency to an evaluation B if - the value of A is used as an operand of B, unless:

— B is an invocation of any specialization of std::kill_dependency (29.3), or

— A is the left operand of a built-in logical AND (&&, see 5.14) or logical OR (||, see 5.15) operator, or

— A is the left operand of a conditional (?:, see 5.16) operator, or

— A is the left operand of the built-in comma (,) operator (5.18); (...)

我能理解为什么在关系之前排序的依赖会在 kill_dependency 调用时停止,但为什么逻辑与、或、逗号等运算符也会破坏依赖链?

这是否意味着下面的代码有未定义的行为?

//thread1
int y = 2
atomicVal.store(true);

//thread2
auto x = atomicVal.load(std::memory_order_consume);
cout << x && y;

最佳答案

memory_order_consume 是一种尝试公开用于 C++ 的 asm 级 CPU 功能。 (它是 temporarily deprecated,直到它可以被重新设计成编译器可以在实践中实现的东西,并且不需要源代码中那么多的 kill_dependency 噪音)。理解 CPU 行为是理解旨在公开它的 C++ 设计的关键。

这都是关于数据的依赖,而不是像条件分支那样的控制依赖。 C++11: the difference between memory_order_relaxed and memory_order_consume[[carries_dependency]] what it means and how to implement有更多细节。

例如add x2, x2, x3 指令在其两个输入寄存器都准备就绪之前无法执行,ldr w1, [x2] 也无法在地址为准备好了,所以如果 x2 来自另一个负载,它会自动排在这个负载之前。 (假设 CPU 硬件设计为不违反因果关系,例如通过进行值预测或 DEC Alpha 在极少数情况下违反因果关系所做的任何事情)。但是 cbz w1, reg_was_zero 是可以预测的,所以让 reg_was_zero: ldr w3, [x4] 等待产生 w1 的负载是不够的。 (顺便说一句,这是 AArch64 asm,一个保证依赖排序的弱排序 ISA。)

||left && right 的短路评估在逻辑上与 if(left) right 相同/strong>,因此即使左侧尚未执行,也可以预期分支预测 + 推测执行会运行右侧。 没有数据依赖,只有控制依赖。

显然逗号 left, right 不会在两侧之间创建任何连接,它基本上是一种填充 left 的方式; right; 变成一个表达式。

当然,如果您在左侧和右侧都使用相同的变量,那么数据依赖性可能会以这种方式存在,但它不是由运算符(operator)创建的。

关于c++ - 为什么逻辑 AND/OR 的左操作数不依赖于父评估?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66963222/

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