zoukankan      html  css  js  c++  java
  • 对于伪共享的错误理解

    昨天学到了伪共享,基本理解了大致的意思:

    1,数据变量存储的基本单位是缓存行,有计算机操作系统基础的都知道,现代的计算机为了解决cpu和主存之间的速度差异(主要是cpu比主存的与运行速度快太多了),提出了cache的概念,也就是缓存,一般会有多级缓存,这个不多说。但是现在的这些缓存行的大小一般都是蛮大的,比如说有64个字节,所以一个缓存行就可以存储多个变量,比如说一个long类型的变量是8个字节,所以一行可以扔8个long。

    2.那么现在cpu读取数据就是要读取这个数据在的缓存行,而且现在问题来了,由于什么MESI协议(cv过来的),

    MESI协议

    多核CPU都有自己的专有缓存(一般为L1,L2),以及同一个CPU插槽之间的核共享的缓存(一般为L3)。不同核心的CPU缓存中难免会加载同样的数据,那么如何保证数据的一致性呢,就是MESI协议了。
    在MESI协议中,每个Cache line有4个状态,可用2个bit表示,它们分别是:
    M(Modified):这行数据有效,数据被修改了,和内存中的数据不一致,数据只存在于本Cache中;
    E(Exclusive):这行数据有效,数据和内存中的数据一致,数据只存在于本Cache中;
    S(Shared):这行数据有效,数据和内存中的数据一致,数据存在于很多Cache中;
    I(Invalid):这行数据无效。

    那么,假设有一个变量i=3(应该是包括变量i的缓存块,块大小为缓存行大小);已经加载到多核(a,b,c)的缓存中,此时该缓存行的状态为S;此时其中的一个核a改变了变量i的值,那么在核a中的当前缓存行的状态将变为M,b,c核中的当前缓存行状态将变为I

    在多核计算机中,也就是现在有多个cpu,一个cpu读取了变量a所在的缓存行以后,对于这个缓存行它就失效了,所以导致一个关键的问题。

    3.是什么问题呢?就是一个缓存行中可能不止有个a还有一个b,在a的旁边,那么假如现在cpu1读取了变量a,那么变量b也就不能在用了,所以对于现在有个cpu2想用这个b,那么它就不能用缓存里的,只能到主存中去拿,那么肯定会变慢啊(不然为什么加缓存)。感觉这里特别像被volatile修饰了一样。

    4.对于这个问题解决方法我就不多说了。我说一下,我脑子不好的问题,思想出了问题,我在想的是既然已经加了volatile修饰,那么肯定会到主存中拿数据啊,为什么会变慢呢?良久以后,我发现了问题所在,volatile修饰的只是a,那么对于cpu2来说,他只是想要一个b,跟a又有什么关系呢?他可以从cache中拿啊,而且对于没有被volatile修饰的变量来说,你即使发生了伪共享,但是不会触及到主存那一块中,因为没有被volatile修饰以后,它就不会每次修改以后都更新主存中的值他只是一个普通的变量,存在可见性的问题,那么即使别的内核需要更新缓存行,也就不会有正确的结果,相应的速度也就比有修饰volatile的快了,因为jvm会将这些值存储在线程栈中,不会及时回写给主内存, 各个线程之间也就不会互相干扰。

    5.我不知道我这么想对不对,但是这是我看了蛮多博客以后的结论了,如果你觉得有问题,或者有疑义,可以评论告诉我。

  • 相关阅读:
    深入了解 Flink 网络栈(二):监控、指标和处理背压
    物联网安全技术提高区块链应用数据的可信度
    威胁快报|Bulehero挖矿蠕虫升级,PhpStudy后门漏洞加入武器库
    Ververica Platform-阿里巴巴全新Flink企业版揭秘
    重磅 | 阿里云与MongoDB达成战略合作,成为全球唯一提供最新版MongoDB的云厂商
    阿里巴巴叶军:政企数字化转型,现在是最重要的时机
    Canonical 开源 MicroK8 | 云原生生态周报 Vol. 25
    nyoj42——连通图加欧拉(连通图板子)dfs
    nyoj38——最小生成树
    nyoj20——有向无环图深搜模板
  • 原文地址:https://www.cnblogs.com/cold-windy/p/11746630.html
Copyright © 2011-2022 走看看