MemoryBarrier[通俗易懂]

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

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

查了下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://javaforall.net/157894.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 技术解析:阿里云 AnalyticDB 如何实现全球性能第一

    技术解析:阿里云 AnalyticDB 如何实现全球性能第一简介: 北京时间2020年5月4日,TPC官网正式公布,阿里云自研云原生数据仓库AnalyticDB通过严苛的TPC-DS全流程测试,性能较前世界纪录提升29%,单位成本仅为其1/3,再次成为全球性能领先的数据仓库。本文将对AnalyticDB进行全面解析,详细阐述其技术架构及存储和查询技术,并对AnalyticDB的下一步发展做出展望。前言随着云时代全面到来,企业数据需求不断变化,从传统的BigData逐渐向FastData演进,主要表现在如下

    2022年9月17日
    0
  • win ce 编译运行自定义控件提示:Result code: 0x80040154 错误解决

    win ce 编译运行自定义控件提示:Result code: 0x80040154 错误解决

    2021年8月8日
    51
  • Android端 WebP图片压缩与传输的一点探索

    Android端 WebP图片压缩与传输的一点探索简介直到4g时代,流量依然是宝贵的东西。而移动网络传输中,最占流量的一种载体:图片,成为了我们移动开发者不得不关注的一个问题。我们关注的问题,无非是图片体积和质量如何达到一个比较和谐的平衡,希望得到质量不错的图片同时体积还不能太大。走在时代前列的谷歌给出了一个不错的答案——WebP。WebP是一种图片文件格式,在相同的压缩指标下,webp的有损压缩能比jpg小25-34%。而在

    2025年5月25日
    0
  • Activity 跳转详解

    Activity 跳转详解Activity跳转详解你好!我是Graydalf,有可能也叫Gdalf~今天被朋友问到如何设置一个广播来启动一个应用并显示数据,于是将自己了解到的记录下来,有什么较为DEMO的地方希望你能留言告诉我,因为我们都是GitHub嘛~~本节说明:Activity跳转的方式;跳转传值问题(包括非Activity的跳转到Activity);跳转传递值时生命周期回调函数调用情况

    2022年5月22日
    32
  • 老庄结构设计官网_互联网颗粒度的名词解释

    老庄结构设计官网_互联网颗粒度的名词解释    本文是对上篇MGN论文阅读做一个详细的补充,主要补充其结构设计及技术实现细节。文章内容整合来自云从科技资深算法研究员袁余锋老师,通过以下四个方面来讲解本次课题:1、ReID的定义及技术难点;2、常用数据集与评价指标简介;3、多粒度网络(MGN)的结构设计与技术实现;4、ReID在行人跟踪中的应用分析与技术展望ReID是行人智能认知的其中一个研究方向,行人智能认知是人脸识别之后比较重要…

    2022年10月6日
    0
  • x86和x64的区别[通俗易懂]

    x86和x64的区别[通俗易懂]整理了下网上的资料,归类了下,大似表述是这样的:IBM/PC兼容机,也就是Intel的i80x86指令架构,就简称了x86。x86并不是指32位环境,而是指80×86架构,这个架构目前有32位,64位

    2022年8月4日
    4

发表回复

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

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