问题标签 [instruction-reordering]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 修改前排序一致性
放宽排序 标记为 std::memory_order_relaxed 的原子操作不是同步操作,它们不对内存进行排序。它们只保证原子性和修改顺序的一致性。例如,x 和 y 最初为零,
允许产生 r1 == r2 == 42,因为尽管 A 在 B 之前排序并且 C 在 D 之前排序,但没有什么可以阻止 D 在 y 的修改顺序中出现在 A 之前,并且 B 在修改中出现在 C 之前x 的顺序。
问题:是什么赋予上述代码属性A 在 B 之前排序而C 在 D 之前排序?
编辑:
导致
在带有 -02 选项的 GCC 4.6.1 下
所以我们清楚地看到(A)和(B)已经切换了
java - 如何演示 Java 指令重新排序问题?
使用 Java 指令重新排序,代码的执行顺序由 JVM 在编译时或运行时更改,可能导致不相关的语句无序执行。
编辑: [指令重新排序会产生违反直觉的结果。许多 CPU 架构可以重新排序机器指令的内存交互,即使编译器没有更改指令顺序,也会导致类似的意外结果。因此,术语内存重新排序可能比指令重新排序更合适。]
所以我的问题是:
有人可以提供一个示例 Java 程序/片段,它可靠地显示指令重新排序问题,这也不是由其他同步问题引起的(例如缓存/可见性或非原子 r/w,就像我在这样的演示中失败的尝试一样在我之前的问题中)
需要强调的是,我不是在寻找理论重新排序问题的示例。我正在寻找的是一种通过查看正在运行的程序的不正确或意外结果来实际演示它们的方法。
除非有错误的行为示例,否则仅显示在简单程序的汇编中发生的实际重新排序也可能很好。
cpu - 编译器完成的指令重新排序和 cpu 完成的指令重新排序之间有什么关系?
好的,因此出于性能原因,编译器可以自由地重新排序代码片段。让我们假设一些代码片段,直接翻译成没有应用优化的机器代码,如下所示:
但是智能编译器认为原始顺序非常低效并重新排序相同的代码,以便生成的机器指令的新顺序如下:
到目前为止,一切都很好。
这是棘手的部分开始的地方。生成的机器指令将由 cpu 执行,只要保留代码逻辑,cpu 就可以以任何它认为适合性能的方式自由地重新洗牌它们。由于我们正在处理指令重新排序的两个“层”:
- 第一个,由于编译器优化
- 第二个,由于cpu乱序执行
是什么使编译时指令重新排序完全相关?cpu 看到的只是一系列原始机器指令,没有迹象表明编译器执行了任何先前的优化。如果 cpu 引入了自己的重新排序“层”,为什么它不会使编译器设置的指令顺序无效?基本上,是什么迫使 cpu 尊重编译器优化?编译时重排序和运行时重排序如何“合作”,后者如何补充前者?
compiler-construction - 编译器和处理器优化如何加速代码执行?
在Linux Kernel Development (3rd Edition)中,Kernel Synchronization Methods, Ordering and Barriers。有一个例子:
我对本书中的陈述感到困惑:
同样,在没有内存屏障的情况下,可以在将 pp 设置为 p 之前将 b 设置为 pp。
那么,作者的意思是如果没有read_barrier_depends()
,b = *pp
会在之前被执行pp = p
吗?这怎么可能?
c# - Interlocked.CompareExchange 指令重新编码初始值
我想知道是否可以将以下代码中的初始值重新排序为在计算之后导致未定义的行为。
在将总值分配给初始值和实际计算之间是否需要内存屏障?
正如我目前所理解的,没有障碍可以通过删除导致线程安全问题的初始值的方式进行优化,因为可以使用陈旧的值计算 computedValue,但 CompareExchange 将不再检测到这一点:
此处是否缺少局部变量的特殊规则来解释为什么该示例不使用内存屏障?
java - 如何在 jcstress 测试中产生指令重新排序
当我怀疑 java 语言规范允许某些指令重新排序时,我想在 jcstress 测试中重现它。我怎样才能做到这一点?例如,在下面的代码中,加载和存储指令(我相信)允许在某些运行时环境中重新排序执行。但是,当我在 Intel x84_64 Ubuntu 中运行 jcstress 时,结果并未显示发生任何重新排序。
php - 按另一个数组中给出的特定顺序对数组值进行排序
我有这个顺序正确的数组:
这些文件位于多个服务器和数据库的不同表中。
在搜索文档结束时,我通常会得到一个具有以下结构但元素混乱的数组:
//模拟变量:
输出:
我尝试使用它,但它不起作用。我收到一个错误,因为第二个参数需要是整数:
在调查此本机功能均无效后:
https://www.w3schools.com/php/php_arrays_sort.asp
如何获得正确的值顺序?
预期的示例,按 $orderDoc 订单和按数字文档排序:
更新我尝试使用自定义函数但得到一些错误:
输出:
c++ - 我们是否保证任何原子写入都会立即将原子变量的新值存储在主存储器中?
所以,我阅读了很多关于指令和内存重新排序以及我们如何防止它的内容,但我仍然没有回答一个问题(可能是因为我不够专心)。我的问题是:我们是否保证任何原子写入都会立即将原子变量的新值存储在主存储器中?我们来看一个小例子:
所以,在这里我们的断言肯定可以触发,因为我们使用std::memory_order_relaxed并且不阻止任何指令重新排序(或编译时的内存重新排序,我想这是同一件事)。但是如果我们在 WritingValues 中设置一些编译器屏障来防止指令重新排序,一切都会好吗?我的意思是,x.store(true, std::memory_order_relaxed) 是否保证该特定原子变量的写入将直接进入内存,没有任何延迟?还是x.load(std::memory_order_relaxed)保证该值将从内存中读取,而不是从具有无效值的缓存中读取?也就是说,本店只保证操作的原子性并具有与通常的非原子变量相同的内存行为,或者它也对内存行为有影响?
java - Java中的StoreStore内存屏障是否禁止读写重新排序?
现在我们有
有没有可能实际的执行顺序如下
如果可能,如何解释似乎违反The Java volatile Happens-Before Guarantee
.
据我所知,volatile语义是使用下面的JMM内存屏障添加策略实现的
现在如果我们有两个java线程如下
线程 1
线程 2
根据“The Java volatile Happens-Before Guarantee”,<code>Load A应该是happens-before Load C
when Load volatile B
is after Store volatile B
,但如果Load A
可以重新排序为“after Store volatile B”,如何保证Load A is before Load C
?
c++ - 内存模型,负载获取语义实际上是如何工作的?
Q1:我知道缓存一致性、存储缓冲区和失效队列是内存重新排序的根本原因?
存储释放是可以理解的,必须等待所有加载和存储完成后才能将标志设置为 true。
关于加载获取,原子加载的典型用法是等待标志。假设我们有 2 个线程:
编辑:在线程 1 中,它应该是一个 while 循环,但我从上面的文章中复制了逻辑。因此,假设内存重新排序是及时发生的。
Q2 : 因为 (1) 和 (2) 取决于 if 条件,CPU 必须等待 ready_flag,是否意味着 write-release 就足够了?在这种情况下如何进行内存重新排序?
Q3:显然我们有load-acquire,所以我猜 mem-reorder 是可能的,那么我们应该在哪里放置栅栏,(1)或(2)?