cpu性能探究 :cache line 原理



参考:

一个讲解Direct Mapped Cache非常深入浅出的文章:

http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Memory/direct.html

CPU cache

http://en.wikipedia.org/wiki/CPU_cache

http://blog.csdn.net/zqy2000zqy/article/details/1137895

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

总体认识,

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算法就很简单了, 不用取模, 直接把内存地址的某几个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

http://software.intel.com/en-us/articles/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) 频繁更新的存储和不频繁更新的存储分开.

时间: 2024-11-08 23:50:30

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

cpu性能探究-Linux Cache机制

 在阅读文章前,您应该具备基本的存储器层次结构知识,至少要了解局部性原理.要详细了解cache基本原理,可以参考本书<深入理解计算机系统>中存储器体系结构一章: 带着疑问来看文章,cache对于程序员是不可见的,它完全是由硬件控制的,为什么在linux内核中还有cache.h这个头文件,定义了一些关于cache的结构? 1. cache概述 cache,中译名高速缓冲存储器,其作用是为了更好的利用局部性原理,减少CPU访问主存的次数.简单地说,CPU正在访问的指令和数据,其可能会被以后多次

多线程之 Cache Line 与伪共享

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

[z]计算机架构中Cache的原理、设计及实现

前言 虽然CPU主频的提升会带动系统性能的改善,但系统性能的提高不仅仅取决于CPU,还与系统架构.指令结构.信息在各个部件之间的传送速度及存储部件的存取速度等因素有关,特别是与CPU/内存之间的存取速度有关. 若CPU工作速度较高,但内存存取速度相对较低,则造成CPU等待,降低处理速度,浪费CPU的能力. 如500MHz的PⅢ,一次指令执行时间为2ns,与其相配的内存(SDRAM)存取时间为10ns,比前者慢5倍,CPU和PC的性能怎么发挥出来? 如何减少CPU与内存之间的速度差异?有4种办法:

cpu指令重排序的原理

目录: 1.重排序场景 2.追根溯源 3.缓存一致性协议 4.重排序原因 一.重排序场景 class ResortDemo { int a = 0; boolean flag = false; public void writer() { a = 1; //1 flag = true; //2 } Public void reader() { if (flag) { //3 int i = a * a; //4 …… } } } 当两个线程 A 和 B,A 首先执行writer() 方法,随后

linux查看CPU性能及工作状态的指令

衡量CPU性能的指标: 1,用户使用CPU的情况:CPU运行常规用户进程CPU运行niced processCPU运行实时进程 2,系统使用CPU情况:用于I/O管理:中断和驱动用于内存管理:页面交换用户进程管理:进程开始和上下文切换 3,WIO:用于进程等待磁盘I/O而使CPU处于空闲状态的比率. 4,CPU的空闲率,除了上面的WIO以外的空闲时间 5,CPU用于上下文交换的比率 6,nice 7,real-time 8,运行进程队列的长度 9,平均负载 Linux中常用的监控CPU整体性能的

Intel台式机CPU性能对比分析(不定期更新)

Intel台式机CPU性能对比(综合) 双核-四核CPU(综合) 型号 主频/睿频 核心/线程 制程 功耗 三级Cache 核显 内存控制 i7-6700K 4.0/4.2GHz 4/8 14nm 95W 8MB HD 530 DDR4-2133 i7-6700 3.4/4.0GHz 4/8 14nm 65W 8MB HD 530 DDR4-2133 i7-6700T 2.8/3.6GHz 4/8 14nm 35W 8MB HD 530 DDR4-2133 i7-4790K 4.0/4.4GHz

linux查看CPU性能及工作状态的指令mpstat,vmstat,iostat,sar,top

衡量CPU性能的指标: 1,用户使用CPU的情况:CPU运行常规用户进程CPU运行niced processCPU运行实时进程 2,系统使用CPU情况:用于I/O管理:中断和驱动用于内存管理:页面交换用户进程管理:进程开始和上下文切换 3,WIO:用于进程等待磁盘I/O而使CPU处于空闲状态的比率. 4,CPU的空闲率,除了上面的WIO以外的空闲时间 5,CPU用于上下文交换的比率 6,nice 7,real-time 8,运行进程队列的长度 9,平均负载 Linux中常用的监控CPU整体性能的

Oracle RAC cache fusion原理测试

Oracle RAC cache fusion是RAC最核心的工作机制,他把所有实例的SGA虚拟成一个大的SGA区,每当不同的实例请求相同的数据块,这个数据块就需要在实例间进行传递.那到底什么时候传递呢?加上RAC有4个节点,其中的一个节点执行了一条SQL是全表扫描一张表,这个时候这个节点把这张表的数据加载到缓存:其他的节点如果需要相同的数据块会取第一个节点的数据,那是需要的时候去,还是第一个节点推送呢?   实验设定: 1.清空4个节点的share pool和databuffer,其实当清除第

CPU性能监测介绍

CPU的性能监测包含以下部分: * 检查系统运行队列并确保每个核心上不超过3个可运行进程* 确保CPU利用率的用户时间和系统时间在70/30之间* 当CPU花费更多的时间在system mode上时,更有可能是因过载而试图重新调度优先级* 运行CPU限制型应用比IO限制型应用更易出现性能瓶颈 性能调优是找出系统瓶颈并消除这些瓶颈的过程.很多系统管理员认为性能调优仅仅是调整一下内核的参数即可解决问题,事实上情况并不是这样.性能调优是实现操作系统的各个子系统之间的平衡性,这些子系统包括: * CPU