MemoryBarrier方法[通俗易懂]

MemoryBarrier方法[通俗易懂]查了下MSDN的解释:MemoryBarrierisrequiredonlyonmultiprocessorsystemswithweakmemoryordering(forexample,asystememployingmultipleIntelItaniumprocessors).Syn…

大家好,又见面了,我是你们的朋友全栈君。

查了下MSDN的解释:

             MemoryBarrier is required only on multiprocessor systems with weak memory ordering (for example, a system employing multiple Intel Itanium processors).

             Synchronizes memory access as follows: The processor executing the current thread cannot reorder instructions in such a way that memory accesses prior to the call to MemoryBarrier execute after memory accesses that follow the call to MemoryBarrier.

            就是说多核处理器会对运行CPU指令顺序重排优化,MemoryBarrier可以阻止指令重排,调用Thread.MemoryBarrier()之后的代码中内存访问不能再这之前就完成了。也就是它可以限制指令重排和内存读写的缓存。

         下面有段代码,在release编译情况下会死循环(debug应该是没做instructions reorder而不会有问题)

            bool complete = false;
            var t = new Thread(() =>
            {
   
   
                bool toggle = false;
                while (!complete)
                    toggle = !toggle;
            });
            t.Start();
            Thread.Sleep(1000);
            complete = true;
            t.Join();

问题原因:

1.编译器、CLR或者CPU可能重新排序了程序指令,以此提高效率。

2.编译器、CLR或者CPU引入缓存优化导致其他的线程不能马上看到变量值的更改。

 

尝试了下将Thread.MomoryBarrier加到while中,保证complete读到的最新的:

此例子中MomoryBarrier 应该时解决jit时过度优化,虽然两个核心cache line 不会及时同步,complete 值修改通过MSIE协议也很快的通知到其他核心。

出现死循环在于jit 任魏complete值一直是false,并没有执行load操作,而是直接判断true跳转。

            bool complete = false;
            var t = new Thread(() =>
            {
   
   
                bool toggle = false;
                while (!complete)
                {
   
   
                   Thread.MemoryBarrier();
                    toggle = !toggle;
                }
            });
            t.Start();
            Thread.Sleep(1000);
            complete = true;
            t.Join();

在看一个例子:(来自《window 并发编程指南》内存模型部分)
MyObject mo= ..;
int f= mo.field;
if(f==0)
{
  //same operation
  Console.WriteLine(f);
}
如果mo.field 在读取和Console.WriteLine相隔足够远,那么编译器可能会认为读mo.field 读取两遍会更有效,被编译成如下代码:
MyObject mo= ..;
if(mo.filed==0)
{
  //same operation
  Console.WriteLine(mo.field);
}
编译器可能判断,保留这个值是否给寄存器带来压力并导致栈空间的低效使用,并且之个分支是否很少被使用(因此f值就不需要多次)
这样带来多线程问题,将f值使用volatitle修饰,可禁止这种优化


转载于:https://www.cnblogs.com/lulu/archive/2012/05/26/2519580.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/157901.html原文链接:https://javaforall.net

(0)
上一篇 2022年7月12日 下午5:16
下一篇 2022年7月12日 下午5:36


相关推荐

  • 大数据ETL开发之图解Kettle工具(入门到精通)

    大数据ETL开发之图解Kettle工具(入门到精通)0ETL简介ETL(Extract-Transform-Load的缩写,即数据抽取、转换、装载的过程),对于企业或行业应用来说,我们经常会遇到各种数据的处理,转换,迁移,所以了解并掌握一种ETL工具的使用,必不可少。市面上常用的ETL工具有很多,比如Sqoop,DataX,Kettle,Talend等,作为一个大数据工程师,我们最好要掌握其中的两到三种,这里我们要学习的ETL工具是Kettle!1Kettle简介1.1Kettle是什么Kettle是一款国外开源的ETL工具,纯ja

    2022年6月13日
    60
  • MySQL数据库备份脚本

    MySQL数据库备份脚本概述远程或者本地备份mysql数据库,并且保存最新7天的备份内容。#!/bin/sh#definevariables#thelogininformationofyourmysqldb.login_user=""login_passwd="&a

    2022年6月13日
    39
  • Linux 查看CUDA 版本

    Linux 查看CUDA 版本Linux 查看 CUDA 版本

    2026年3月26日
    3
  • Android 8.0 RIL框架分析

    Android 8.0 RIL框架分析原文地址 https blog csdn net article details nbsp nbsp 前言 AndroidO 的版本对 RIL 的框架的通信功能进行了改动 不在使用 sockect 进行通讯 而改用 HIDL 进行通信 这里结合 7 0 和 8 0 的源码 分析目前的 RIL 框架 如有错误还请不吝指正 RIL 的入口 xref hardware ril

    2026年3月16日
    1
  • 大数据平台展示可视化效果,echarts图表实战项目(源码50套)「建议收藏」

    大数据平台展示可视化效果,echarts图表实战项目(源码50套)「建议收藏」最近接了个任务需要用H5在前台两个大电视上做两页数据展示公司的产品数据,效果要高大上,充分展示咱们公司的实力,给各位来公司参观的大能们留下深刻的印象。还好之前接触过HTML5,所以第一时间想到就是echarts,这个框架对于数据展示尤其图表类处理的还是非常强大和炫酷的。说干就干,首先到官网上把框架下下来,各组件Demo和API都熟悉下,对于你想要的东西和效果心里有个底,就开始动工了。官网地址是:https://echarts.apache.org,里面的Demo都是代码和效果图文并貌,还可以在线修改

    2022年10月12日
    7
  • Apache Web服务器安全配置全攻略[通俗易懂]

    Apache Web服务器安全配置全攻略[通俗易懂]作为最流行的Web服务器,ApacheServer提供了较好的安全特性,使其能够应对可能的安全威胁和信息泄漏。   Apache服务器的安全特性  1、采用选择性访问控制和强制性访问控制的安全策略  从Apache或Web的角度来讲,选择性访问控制DAC(DiscretionaryAccessControl)仍是基于用户名和密码的,强制性访问控制MAC(Mand

    2025年7月10日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号