热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

CPUCache模型

计算机中,所有的运算操作都是由CPU的寄存器来完成的,CPU指令的执行过程需要涉及数据的读取和写入操作,CPU所能访问的所有数据只能是计算

    计算机中,所有的运算操作都是由CPU的寄存器来完成的,CPU指令的执行过程需要涉及数据的读取和写入操作,CPU所能访问的所有数据只能是计算机的主存(通常RAM)。

    CPU和主存两边的速度严重的不对等,通过传统FSB(Front Side Bus)直接内存的访问方式很明显会导致CPU资源受到大量的限制,降低CPU整体的吞吐量,于是才有了在CPU和主内存之间增加缓存的设计,缓存有一级缓存(一级缓存又分为一级指令缓存和一级数据缓存)、二级缓存、三级缓存,主存到CPU之间的缓存的访问速度是越来越快的,这种方式极大的提高了CPU的吞吐能力,缓存模型如下:

 

CPU Cache中的最小缓存单位是Cache Line,CPU缓存由许多个Cache Line构成,一个缓存行64个字节。由于缓存的出现,虽然提高了CPU的吞吐能力,但是同时也引入了缓存不一致的问题。比如在多线程时i++就可能会产生缓存不一致性的问题。主流的解决方案是:

1、锁总线

2、通过缓存一致性协议

锁总线是一种悲观的实现方式,CPU和其他组建的通信都是通过总线(数据总线、控制总线、地址总线)来进行,如果采用总线加锁的方式,则会阻塞其他CPU对其他组建的访问,从而使得只有一个CPU能够访问这个变量的内存,这种方式效率低下,一般都是通过第二种方式来解决不一致的问题。

缓存一致性协议中的MESI协议保证了每个缓存中使用的共享变量副本都是一致的。当CPU在操作Cache中的数据时,如果发现该变量是一个共享变量,也就是说在其他的CPU Cache中也存在一个副本,那么进行如下操作:

1、读取操作,不做任何处理,只是将Cache中的数据读取到寄存器。

2、写入操作,发出信号通知其他CPU将该变量的Cache Line置为无效状态,其他CPU在进行该变量读取的时候不得不到主内存中再次获取。

 

这里举个栗子:如果x,y变量在一个缓存行里,开启两个线程对x和y变量进行修改,那么一个线程修改x/y变量时得通知另一个线程修改过了x/y变量,这样会影响它的性能。

如果我们把x和y放在不同的缓存行里,那么它们之间就不会相互影响,这个也叫缓存行对齐。

 

补充知识:

一个java对象在内存中的存储布局:对象头markword(8个字节)、类型指针class pointer(8个字节,经过压缩后是4个字节)、实例数据instance data(看实际的数据大小,比如一个long类型对象占8个字节),对齐padding(这块是看前面的数据量能否被8个字节整除,不能才去补齐,比如markword—8字节+class pointer—8字节+instance data—long类型+int类型—8+4字节,那么padding就是4字节)。

那么x所在的对象里加上一些冗余的数据使得该对象为64字节,那么x和y就不在一个缓存行了。实际应用中,如disruptor就采用了缓存行对齐伪共享的技术提升了性能。

 


推荐阅读
  • 本文深入解析了JDK 8中HashMap的源代码,重点探讨了put方法的工作机制及其内部参数的设定原理。HashMap允许键和值为null,但键为null的情况只能出现一次,因为null键在内部通过索引0进行存储。文章详细分析了capacity(容量)、size(大小)、loadFactor(加载因子)以及红黑树转换阈值的设定原则,帮助读者更好地理解HashMap的高效实现和性能优化策略。 ... [详细]
  • 兆芯X86 CPU架构的演进与现状(国产CPU系列)
    本文详细介绍了兆芯X86 CPU架构的发展历程,从公司成立背景到关键技术授权,再到具体芯片架构的演进,全面解析了兆芯在国产CPU领域的贡献与挑战。 ... [详细]
  • 本文详细介绍了 com.apollographql.apollo.api.internal.Optional 类中的 orNull() 方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 本文将介绍如何在混合开发(Hybrid)应用中实现Native与HTML5的交互,包括基本概念、学习目标以及具体的实现步骤。 ... [详细]
  • 如果应用程序经常播放密集、急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了。因为MediaPlayer存在如下缺点:1)延时时间较长,且资源占用率高 ... [详细]
  • Java高并发与多线程(二):线程的实现方式详解
    本文将深入探讨Java中线程的三种主要实现方式,包括继承Thread类、实现Runnable接口和实现Callable接口,并分析它们之间的异同及其应用场景。 ... [详细]
  • 在《Cocos2d-x学习笔记:基础概念解析与内存管理机制深入探讨》中,详细介绍了Cocos2d-x的基础概念,并深入分析了其内存管理机制。特别是针对Boost库引入的智能指针管理方法进行了详细的讲解,例如在处理鱼的运动过程中,可以通过编写自定义函数来动态计算角度变化,利用CallFunc回调机制实现高效的游戏逻辑控制。此外,文章还探讨了如何通过智能指针优化资源管理和避免内存泄漏,为开发者提供了实用的编程技巧和最佳实践。 ... [详细]
  • PHP-Casbin v3.20.0 已经发布,这是一个使用 PHP 语言开发的轻量级开源访问控制框架,支持多种访问控制模型,包括 ACL、RBAC 和 ABAC。新版本在性能上有了显著的提升。 ... [详细]
  • 一个建表一个执行crud操作建表代码importandroid.content.Context;importandroid.database.sqlite.SQLiteDat ... [详细]
  • 浅析python实现布隆过滤器及Redis中的缓存穿透原理_python
    本文带你了解了位图的实现,布隆过滤器的原理及Python中的使用,以及布隆过滤器如何应对Redis中的缓存穿透,相信你对布隆过滤 ... [详细]
  • 本文回顾了作者初次接触Unicode编码时的经历,并详细探讨了ASCII、ANSI、GB2312、UNICODE以及UTF-8和UTF-16编码的区别和应用场景。通过实例分析,帮助读者更好地理解和使用这些编码。 ... [详细]
  • 在多线程并发环境中,普通变量的操作往往是线程不安全的。本文通过一个简单的例子,展示了如何使用 AtomicInteger 类及其核心的 CAS 无锁算法来保证线程安全。 ... [详细]
  • com.hazelcast.config.MapConfig.isStatisticsEnabled()方法的使用及代码示例 ... [详细]
  • 本文探讨了如何通过编程手段在Linux系统中禁用硬件预取功能。基于Intel® Core™微架构的应用性能优化需求,文章详细介绍了相关配置方法和代码实现,旨在帮助开发人员有效控制硬件预取行为,提升应用程序的运行效率。 ... [详细]
  • 本文深入探讨了NoSQL数据库的四大主要类型:键值对存储、文档存储、列式存储和图数据库。NoSQL(Not Only SQL)是指一系列非关系型数据库系统,它们不依赖于固定模式的数据存储方式,能够灵活处理大规模、高并发的数据需求。键值对存储适用于简单的数据结构;文档存储支持复杂的数据对象;列式存储优化了大数据量的读写性能;而图数据库则擅长处理复杂的关系网络。每种类型的NoSQL数据库都有其独特的优势和应用场景,本文将详细分析它们的特点及应用实例。 ... [详细]
author-avatar
YooHoo
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有