C++ 不订购带记忆屏障或锁的指令的范围

C++ 不订购带记忆屏障或锁的指令的范围,c++,memory,concurrency,memory-barriers,barrier,C++,Memory,Concurrency,Memory Barriers,Barrier,我找不到有关编译器在看到锁或内存障碍时停止执行指令重新排序的范围的信息 例如在下面的伪代码中参考C++ Lang/P> 如果将锁移动到单独的功能栏与在功能foo中时,在a,x上的指令顺序是否有任何区别 如果lock被完整的内存屏障替换,答案是否相同 int func foo() { read a; x = 10; { lock(mutex); z++; unlock(mutex); } a += 1; return x; } vs 在

我找不到有关编译器在看到锁或内存障碍时停止执行指令重新排序的范围的信息

例如在下面的伪代码中参考C++ Lang/P> 如果将

移动到单独的功能
与在功能
foo
中时,在
a,x
上的指令顺序是否有任何区别

如果
lock
被完整的内存屏障替换,答案是否相同

int func foo()
{
  read a;
  x = 10;
  {
      lock(mutex);
      z++;
      unlock(mutex);
  }
  a += 1;
  return x;
}
vs


在伪代码中,
lock(z)
是什么意思?这应该编译成
z
上的原子事务,比如x86
lock
前缀(
lock add dword[z],1
),还是其他一些ISA上的LL/SC重试循环?您还没有指定一种语言,但C++的内存模型尊重内存排序,比如
z.fetch\u add(1,std::memory\u order\u seq\u cst)
,这在其他函数中可能存在,也可能不存在;如果不能内联函数,则必须假定外部函数调用是一个完整的障碍。可能也有关联:虽然我认为这是在问函数调用本身是否是一个障碍,但如果它可以内联,则不是。将约束移动到函数中永远不会削弱它们。@PeterCordes我故意避免使用Java规范中不存在的术语“内存障碍”,在这里也没有任何承诺。我所说的是,只要约束存在,当移动到另一个函数时,约束就不会变弱。我们也可以反过来说,当约束像第一个示例中那样直接写入函数时,约束不会变得更强。根据上下文的不同,仍然可能根本没有约束。既然这只是伪代码,就没什么可说的了。@PeterCordes我的第一条评论是针对问题的原始代码,它没有增量,只有无关的读写。即使在另一个线程正确锁定时,它们中的大多数也可以在锁和解锁之间重新排序。OP已经存在。
lock(z)
在伪代码中是什么意思?这应该编译成
z
上的原子事务,比如x86
lock
前缀(
lock add dword[z],1
),还是其他一些ISA上的LL/SC重试循环?您还没有指定一种语言,但C++的内存模型尊重内存排序,比如
z.fetch\u add(1,std::memory\u order\u seq\u cst)
,这在其他函数中可能存在,也可能不存在;如果不能内联函数,则必须假定外部函数调用是一个完整的障碍。可能也有关联:虽然我认为这是在问函数调用本身是否是一个障碍,但如果它可以内联,则不是。将约束移动到函数中永远不会削弱它们。@PeterCordes我故意避免使用Java规范中不存在的术语“内存障碍”,在这里也没有任何承诺。我所说的是,只要约束存在,当移动到另一个函数时,约束就不会变弱。我们也可以反过来说,当约束像第一个示例中那样直接写入函数时,约束不会变得更强。根据上下文的不同,仍然可能根本没有约束。既然这只是伪代码,就没什么可说的了。@PeterCordes我的第一条评论是针对问题的原始代码,它没有增量,只有无关的读写。即使在另一个线程正确锁定时,它们中的大多数也可以在锁和解锁之间重新排序。行动已经开始了。
int func foo()
{
  read a;
  x = 10;
  bar();
  a += 1;
  return x;
}

func bar()
{
      lock(mutex);
      z++;
      unlock(mutex);
}