c# - 指令重新排序

标签 c# .net memory-barriers

我对 C#/.NET 中的合法指令重新排序有疑问。

让我们从这个例子开始。我们在某个类中定义了这个方法,其中 _a、_b 和 _c 是字段。

int _a;
int _b;
int _c;
void Foo()
{
   _a = 1; // Write 1
   _b = 1; // Write 2
   _c = 1; // Write 3
}

我们的调用环境看起来像这样。

//memory operations
ClassInstance.Foo();
//memory operations

我想知道当这个方法调用被内联而不是函数调用时,什么样的合法指令重新排序是可能的。更具体地说,我想知道在 Foo() 中重新排序内存操作是否/何时是合法的,而内存操作在它之外(来 self 们之前的示例,//内存操作)。

此外,函数调用(无内联)在某种意义上“产生内存障碍”。就像在函数调用之前或之后发生的内存操作一样,无法使用函数调用内的内存操作重新排序。

如果是这样,当它被编译器内联时,它是否仍然具有这种“内存屏障”行为?

最佳答案

C# Language Specification可以帮助回答这个问题。关于执行顺序的部分是这样说的:

3.10 Execution order

Execution of a C# program proceeds such that the side effects of each executing thread are preserved at critical execution points. ....The execution environment is free to change the order of execution of a C# program, subject to the following constraints:

  • Data dependence is preserved within a thread of execution. That is, the value of each variable is computed as if all statements in the thread were executed in original program order.

  • Initialization ordering rules are preserved (§10.5.4 and §10.5.5).

  • The ordering of side effects is preserved with respect to volatile reads and writes (§10.5.3).

(我遗漏了更多内容;该规范可读性很强,所以如果您真的想深入了解细节,我建议您看一看)。

从本质上讲,规则可以被认为是“抖动可能会重新安排执行顺序,只要执行线程无法观察到差异”。但是,其他 线程可能会观察到差异。在 post by Eric Lippert on the Coverity blog ,他说:

...the CPU may as an optimization choose to [rearrange execution order] provided that doing so is not detectable by the current thread. But that fact could be observed by another thread...

因此,如果操作顺序对其他线程和当前线程都很重要,那么您需要创建一个“关键执行点”;最简单的方法可能是用锁包围语句。

关于c# - 指令重新排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22420368/

相关文章:

c# - HostingEnviornment.QueueBackgroundWorkItem 无法在 azure 辅助角色中工作

c# - C# 的 CRC 4 实现

c++ - 在 ARM 上加载和存储重新排序

c++ - 不能像 store 一样在 x86 上放宽原子 fetch_add 重新排序,稍后加载?

c# - 在 Web 浏览器中运行 WinForms 应用程序

c# - 加载后删除程序集

c# - 为 C# 包装 C++ CLI 类

c# - 如何检查组合框下拉列表是向上显示还是向下显示?

c# - 使用 Code Contracts 指定返回值可能为 null

c# - 我不了解 volatile 和 Memory-Barrier 的是