cache缓存与伪共享

一、cache缓存

cache与主存之间是以块为单位读写的,这样设计是为了符合程序运行的局部性原理--时间局部性原理与空间局部性原理(参见《计算机组成原理》)

二维数组行遍历比列遍历要快,是由于二维数组是按行存储的,cache从主存中读入块,会将同行相邻元素一起写入cache,导致行遍历cache命中率大于列遍历cache命中率。

public class CacheTest {

    static final int LINE_NUM = 1024;
    static final int COLUMN_NUM = 1024;

    public static void main(String[] args){
        long [][] array = new long[LINE_NUM][COLUMN_NUM];
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < LINE_NUM; i++){//行遍历
            for (int j = 0; j < COLUMN_NUM; j++){
                array[i][j] = i*2 + j;
            }
        }
        long endTime = System.currentTimeMillis();
        long cacheTime = endTime - startTime;
        System.out.println("cache time :" + cacheTime);

        startTime = System.currentTimeMillis();
        for (int j = 0; j < COLUMN_NUM; j++){//列遍历
            for (int i = 0; i < LINE_NUM; i++){
                array[i][j] = i*2 + j;
            }
        }
        endTime = System.currentTimeMillis();
        System.out.println("no cache time :" + (endTime - startTime));
    }
}

二、伪共享

伪共享:当一个cache行中有多个变量,多线程不能同时修改更新这多个变量。导致多线程的串行运行

    /*
    * 解决伪共享方法一:cache行为64B,对象头8B,加上变量8B,加上填充的6个无用变量48B,达到一个cache行对应一个变量
    *
    */
    public final static class FiledLong{
        public volatile long value = 0L;
        public long p1,p2,p3,p4,p5,p6;
    }
    /*
     * 解决伪共享方法二:sun.misc.Contended注解
     *
     */
    @Contended
    public final static class FiledLong2{
        public volatile long value = 0L;
    }

原文地址:https://www.cnblogs.com/wqff-biubiu/p/12154570.html

时间: 2024-10-07 05:27:05

cache缓存与伪共享的相关文章

[原理分析]多核下的缓存块伪共享问题

摘要: 本文主要介绍多核下的缓存块伪共享问题,该问题的存在可能导致的有趣现象:两个核跑一个程序,不如单个核跑该程序来得快. 正文: 1.本文考虑的处理器中每个核私有L1缓存,并且多个核共享L2缓存:L1和L2缓存中的缓存块大小都为64bytes,认为double数据类型在本机器上需要8bytes来表示: 2. 缓存一致性的协议:本文考虑的缓存一致性是基于监听(snoop)的写无效(write invalidate)策略,给个简单的例子来说明该策略:当core 0和core 1读访问L2中的缓存块

多线程之 Cache Line 与伪共享

Cache 简介 Cache,即缓存.缓存能提升读取性能,其原理是用性能更好的存储介质存储一部分高频访问的内容,获得总体概率上的速度提升. 在开发中,我们口中的缓存可以是一个变量,或者是 redis.在计算机 CPU 内部,往往指的是 CPU 的各级 cache. Cache 的一致性 由于是高频访问的内容被重复存储到了好几处地方,必然要考虑一致性.你需要及时清除或者更新缓存中过期内容.在程序设计中,使用缓存的架构通常是给定一个过期时间.而对于 CPU Cache,情况就复杂很多. CPU Ca

从Java视角理解CPU缓存和伪共享

CPU是计算机的大脑,它负责执行程序的指令:内存负责存数据,包括程序自身数据.内存比CPU慢很多,现在获取内存中的一条数据大概需要200多个CPU周期(CPU cycles),而CPU寄存器一般情况下1个CPU周期就够了.       网页浏览器为了加快速度,会在本机存缓存以前浏览过的数据:传统数据库或NoSQL数据库为了加速查询,常在内存设置一个缓存,减少对磁盘(慢)的IO.同样内存与CPU的速度相差太远,于是CPU设计者们就给CPU加上了缓存(CPU Cache).如果需要对同一批数据操作很

java 伪共享

MESI协议及RFO请求典型的CPU微架构有3级缓存, 每个核都有自己私有的L1, L2缓存. 那么多线程编程时, 另外一个核的线程想要访问当前核内L1, L2 缓存行的数据, 该怎么办呢?有人说可以通过第2个核直接访问第1个核的缓存行. 这是可行的, 但这种方法不够快. 跨核访问需要通过Memory Controller(见上一篇的示意图), 典型的情况是第2个核经常访问第1个核的这条数据, 那么每次都有跨核的消耗. 更糟的情况是, 有可能第2个核与第1个核不在一个插槽内.况且Memory C

从缓存行出发理解volatile变量、伪共享False sharing、disruptor

volatilekeyword 当变量被某个线程A改动值之后.其他线程比方B若读取此变量的话,立马能够看到原来线程A改动后的值 注:普通变量与volatile变量的差别是volatile的特殊规则保证了新值能马上同步到主内存,以及每次使用前能够马上从内存刷新,即一个线程改动了某个变量的值,其他线程读取的话肯定能看到新的值. 普通变量: 写命中:当处理器将操作数写回到一个内存缓存的区域时.它首先会检查这个缓存的内存地址是否在缓存行中,假设不存在一个有效的缓存行,则处理器将这个操作数写回到缓存,而不

伪共享和缓存行填充,从Java 6, Java 7 到Java 8

关于伪共享的文章已经很多了,对于多线程编程来说,特别是多线程处理列表和数组的时候,要非常注意伪共享的问题.否则不仅无法发挥多线程的优势,还可能比单线程性能还差.随着JAVA版本的更新,再各个版本上减少伪共享的做法都有区别,一不小心代码可能就失效了,要注意进行测试.这篇文章总结一下. 什么是伪共享 关于伪共享讲解最清楚的是这篇文章<剖析Disruptor:为什么会这么快?(三)伪共享>,我这里就直接摘抄其对伪共享的解释: 缓存系统中是以缓存行(cache line)为单位存储的.缓存行是2的整数

共享和伪共享

共享就是一个内存区域的数据被多个处理器访问,伪共享就是不是真的共享.这里的共享这个概念是基于逻辑层面的.实际上伪共享与共享在cache line 上实际都是共享的. CPU访问的数据都是从cache line 中读取的.如果cpu 在cache 中找不到需要的变量,则称缓存未命中. 未命中时,需要通过总线从内存中读取进cache 中.每次读取的内存大小就是一个cache line 的大小. 如果多个CPU访问的不同内存变量被装载到了同一个cache line 中,则从程序逻辑层上讲,并没有共享变

Disruptor的伪共享解决方案

1.术语 术语 英文单词 描述 内存屏障 Memory Barriers 是一组处理器指令,用于实现对内存操作的顺序限制. In the Java Memory Model a volatile field has a store barrier inserted after a write to it and a load barrier inserted before a read of it. 缓存行 Cache line 缓存中可以分配的最小存储单位.处理器填写缓存线时会加载整个缓存线,

伪共享(false sharing),并发编程无声的性能杀手

在并发编程过程中,我们大部分的焦点都放在如何控制共享变量的访问控制上(代码层面),但是很少人会关注系统硬件及 JVM 底层相关的影响因素.前段时间学习了一个牛X的高性能异步处理框架 Disruptor,它被誉为“最快的消息框架”,其 LMAX 架构能够在一个线程里每秒处理 6百万 订单!在讲到 Disruptor 为什么这么快时,接触到了一个概念——伪共享( false sharing ),其中提到:缓存行上的写竞争是运行在 SMP 系统中并行线程实现可伸缩性最重要的限制因素.由于从代码中很难看