加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

允许C#编译器优化局部变量并从内存中重新获取值

发布时间:2020-12-15 03:52:41 所属栏目:百科 来源:网络整理
导读:编辑:我想问当两个线程在没有正确同步的情况下同时访问相同数据时会发生什么(在此编辑之前,该点没有被清楚地表示). 我有一个关于由C#编译器和JIT编译器执行的优化的问题. 考虑以下简化示例: class Example { private Action _action; private void InvokeA
编辑:我想问当两个线程在没有正确同步的情况下同时访问相同数据时会发生什么(在此编辑之前,该点没有被清楚地表示).

我有一个关于由C#编译器和JIT编译器执行的优化的问题.

考虑以下简化示例:

class Example {
    private Action _action;

    private void InvokeAction() {
        var local = this._action;
        if (local != null) {
            local();
        }
    }
}

在示例中,请忽略读取_action可能会产生缓存和过期的值,因为没有volatile说明符或任何其他同步.这不是点:)

编译器(或实际上是运行时的抖动)允许优化到局部变量的赋值,而是从内存中读取_action两次:

class Example {
    private Action _action;

    private void InvokeAction() {
        if (this._action != null) {
            this._action(); // might be set to null by an other thread.
        }
    }
}

当字段_action通过并发分配设置为null时,可能会抛出NullReferenceException.

当然,在这个例子中,这样的“优化”将不会有任何意义,因为将值存储在寄存器中并因此使用局部变量将更快.但是在更复杂的情况下,有没有保证这样工作,如果没有重新读取记忆的价值?

解决方法

根据ECMA规范中定义的内存模型进行合法优化.如果_action是易失性的,内存模型将保证该值只读一次,因此此优化不会发生.

不过,我认为目前微软的CLR实现不会优化局部变量.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读