參考:

一个解说Direct Mapped Cache很深入浅出的文章:


CPU cache


=============================================

整体认识, 

cpu的cache通常较大, 比方 128KB, 被划分为多个有固定大小的cache line, cache line一般是32Byte或64Byte.



CPU内部的cache种类, 至少有三种

1) 指令cache

2) 数据cache 通常有多级 multi-level

3) TLB 加速虚拟地址2物理地址转换





cache entry (cache条目)

包括例如以下部分

1) cache line : 从主存一次copy的数据大小)

2) tag : 标记cache line相应的主存的地址

3) falg : 标记当前cache line是否invalid, 假设是数据cache, 还有是否dirty





cpu訪问主存的规律

1) cpu从来都不直接訪问主存, 都是通过cache间接訪问主存

2) 每次须要訪问主存时, 遍历一遍所有cache line, 查找主存的地址是否在某个cache line中.

3) 假设cache中没有找到, 则分配一个新的cache entry, 把主存的内存copy到cache line中, 再从cache line中读取.





cache中包括的cache entry条目有限, 所以, 必须有合适的cache淘汰策略

一般使用的是LRU策略.

将一些主存区域标记为non-cacheble, 能够提高cache命中率, 减少无用的cache





回写策略

cache中的数据更新后,须要回写到主存, 回写的时机有多种

1) 每次更新都回写. write-through cache

2) 更新后不回写,标记为dirty, 仅当cache entry被evict时才回写

3) 更新后, 把cache entry送如回写队列, 待队列收集到多个entry时批量回写.





cache一致性问题

有两种情况可能导致cache中的数据过期

1) DMA, 有其它设备直接更新主存的数据

2) SMP, 同一个cache line存在多个CPU各自的cache中. 当中一个CPU对其进行了更新.





cpu stall cpu失速

指的是当cache miss时(特别是read cache miss), cpu在等待数据从内存读进去cache中期间, 没事可做.

解决此问题的方法有

1) 超线程技术. CPU在硬件层面, 把一个CPU模拟成两个CPU, 在上层看来是两个CPU. 并发的运行两个线程. 这样当一个线程因cache miss在等待时, 还有一个线程能够运行.





主存的一个地址, 须要被映射进哪个cache line? (术语:Associativity)

依据映射策略的不同而不同





1) 最笨的, 一个地址可被映射进随意cache line (fully associative)

   带来的问题是, 当寻找一个地址是否已经被cache时, 须要遍历每个cache line来寻找, 这个代价不可接受.

   就像停车位能够大家随便停一样, 停的时候简单的, 找车的时候须要一个一个停车位的找了.

   你想下, cpu想知道一个地址是否已经在cache中了, 须要把所有cache line找一边, 那该有多慢?

2) Direct Mapped Cache  (相当于1-way associative)

   这个就是相当于hash了, 每一个地址能被映射到的cache line是固定的. 

   每一个人的停车位是固定分配好的. 能够直接找到.

   缺点是, 由于人多车少, 非常可能几个人争用同一个车位, 导致cache 淘汰频繁. 须要频繁的从主存读取数据到cache, 这个代价也较高.

   因为cache中cache line的个数都是2的指数个. 那么, hash算法就非常easy了, 不用取模, 直接把内存地址的某几个bit位拿出来就可以. 比方cache line有128(2^7)个, cache line的大小是32(2^5)字节, 

   那么一个32位地址的 0~4位作为cache line内部偏移, 5~11位作为cache line的索引就可以. 剩下的bit12~31作为当前cache line的tag. tag的作用时, 当有另外一个地址也映射到同一个cache line时, tag用来比較两个地址是不是同一个地址. 毕竟同一个cache-line能够相应的内存的位置许多个的.





3) 2-way associative

   是fully associative和Direct Mapped Cache的折中.

   2-way, 每个人能够有两个停车位, 这样当一个停车位被占了的时候, 还有机会寻找另外一个. 尽管人数众多, 但同一时候来找停车位的人并不多. (相当于非常多人的车在外面,没有开回来)

   所以, 2-way associative近似的相当于有了2倍大小的cache, 使用Direct Mapped Cache策略.


注意, 这图仅仅统计了cache miss率, 非常显然full-associative是做好的. 可是full-associative导致的推断一个地址是否在cache中的代价是非常昂贵的.所以, 生产环境一般都是2-way associative

======================================================



多线程变成中避免以及识别错误的共享变量方式 主要解决在SMP环境下cache line被频繁刷新的的问题
Avoiding and Identifying False Sharing Among Threads


举例:

// 例如以下代码在SMP环境下存在cache频繁刷新问题
double sum=0.0, sum_local[NUM_THREADS];
#pragma omp parallel num_threads(NUM_THREADS)
{
int me = omp_get_thread_num();
sum_local[me] = 0.0; #pragma omp for
for (i = 0; i < N; i++)
sum_local[me] += x[i] * y[i]; #pragma omp atomic
sum += sum_local[me];
}
由于sum_local数组是个全局变量, 多个线程都会訪问, 而且, 各个线程訪问的地方非常接近, 会导致一个线程更新, 其它CPU的cache line失效.


解决该问题的方法是

1) 不同线程之间尽量少的訪问全局变量, 尽量使用线程局部变量.

2) 假设一定要訪问, 尽量让各个线程自己訪问的区域cacheline对齐.

3) 频繁更新的存储和不频繁更新的存储分开.

cpu性能探究 :cache line 原理的更多相关文章

  1. 程序与CPU,内核,寄存器,缓存,RAM,ROM、总线、Cache line缓存行的作用和他们之间的联系?

    目录 缓存 什么是缓存 L1.L2.L3 为什么要设置那么多缓存.缓存在cup内还是cup外 MESI协议----主流的处理缓存和主存数据不一样问题 Cache line是什么已经 对编程中数组的影响 ...

  2. cache line 伪共享

    https://blog.csdn.net/qq_27680317/article/details/78486220认识CPU Cache CPU Cache概述 随着CPU的频率不断提升,而内存的访 ...

  3. CPU中的cache结构以及cache一致性

    一. 引子 在多线程环境中,经常会有一些计数操作,用来统计线上服务的一些qps.平均延时.error等.为了完成这些统计,可以实现一个多线程环境下的计数器类库,方便记录和查看用户程序中的各类数值.在实 ...

  4. <转>科普CPU Cache line

    转载于http://coolshell.cn/articles/10249.html CPU cache一直是理解计算机体系架构的重要知识点,也是并发编程设计中的技术难点,而且相关参考资料如同过江之鲫 ...

  5. 小师妹学JVM之:cache line对代码性能的影响

    目录 简介 一个奇怪的现象 两个问题的答案 CPU cache line inc 和 add 总结 简介 读万卷书不如行万里路,讲了这么多assembly和JVM的原理与优化,今天我们来点不一样的实战 ...

  6. CPU性能分析工具原理

    转载请保留以下声明 作者:赵宗晟 出处:https://www.cnblogs.com/zhao-zongsheng/p/13067733.html 很多软件都要做性能分析和性能优化.很多语言都会有他 ...

  7. 聊聊高并发(三十四)Java内存模型那些事(二)理解CPU快速缓存的工作原理

    在上一篇聊聊高并发(三十三)从一致性(Consistency)的角度理解Java内存模型 我们说了Java内存模型是一个语言级别的内存模型抽象.它屏蔽了底层硬件实现内存一致性需求的差异,提供了对上层的 ...

  8. 深入理解Cache工作原理

    内容来源:https://zhuanlan.zhihu.com/p/435031232 内容来源:https://zhuanlan.zhihu.com/p/102293437 本文主要内容如下,基本涉 ...

  9. Cache的原理、设计及实现

    Cache的原理.设计及实现 前言 虽然CPU主频的提升会带动系统性能的改善,但系统性能的提高不仅仅取决于CPU,还与系统架构.指令结构.信息在各个部件之间的传送速度及存储部件的存取速度等因素有关,特 ...

随机推荐

  1. Python 做过哪些有趣的项目

          1 icedx   241 天前 via Android   ♥ 1 考虑到Windows 下的类Alfred 软件都太傻逼 自己用PyQT 写了一个       2 crazyxin19 ...

  2. 利用httpclient和多线程刷訪问量代码

    缘起于玩唱吧,由于唱吧好友少,訪问量低,又不想加什么亲友团之类的,主要是太麻烦了,于是我就琢磨唱吧的訪问机制,准备用java的httpclient库来进行刷訪问量,想到动态IP反复使用就想到了用多线程 ...

  3. activity入门2

    1.如何获取其他应用的包名和类名? 点击和查看logcat第一条信息2.第二步Intent intent = new Intent();intent.setClassName("com.an ...

  4. PHP - 多文件上传

    <html> <head> <meta charset="utf-8"> <title>index_uploads</titl ...

  5. Qt序列化格式分析(qint,QString)(非常简单好用)

    最近项目需要进行QT开发环境下对传输对象进行序列化与反序列化处理,对基本类型的处理在使用QT默认的序列化方式还是完全手工序列化这两种方式之间有些犹疑不定,边想了解下QT默认序列化基本类型的格式,项目中 ...

  6. Windows8下通过IPv4地址访问Tomcat

    最近在做Android开发,手机客户端需要通过IPv4地址访问电脑启动的Web应用服务. 在Windows 7不需要做什么设置,localhost,127.0.0.1或者192.168.0.100都可 ...

  7. Connection reset by peer问题分析

    extremetable导出excel,弹出一个下载窗口,这时不点下载而点取消,则报下面的异常: ClientAbortException Caused by: java.net.SocketExce ...

  8. JAVA_2Lesson

    package test; public class abc { public static void main(String[] arg) { int[][] xx=new int[3][]; xx ...

  9. 从 Racket 入门函数式编程

    一直想学学LISP,今天总算开了个头.如今学习LISP不是为了立就可以以用于实际项目的应用,而是为了学习一下函数式的思维方式,可以更加深入的了解计算的本质,可以更好的用C++, Java, Pytho ...

  10. Oracle数据库索引使用及索引失效总结

    容易引起oracle索引失效的原因很多: 1.在索引列上使用函数.如SUBSTR,DECODE,INSTR等,对索引列进行运算.需要建立函数索引就可以解决了. 2.新建的表还没来得及生成统计信息,分析 ...