高速缓冲存储器 - Buffer和Cache的区别

Linux磁盘缓冲区与页高速缓存的理解与应用
本文深入探讨了Linux系统中磁盘缓冲区与页高速缓存的区别与联系,解释了它们在系统性能优化中的作用,并详细阐述了buffer与cache在操作系统层面的具体操作和应用场景。

linux:磁盘缓冲区和页高速缓存的联系与区别
摘自:http://stackoverflow.com/questions/6345020/linux-memory-buffer-vs-cache

概念上的区别:
  1. buffer是块设备的内存读写缓冲区,而page cache是文件系统的概念。
  2. A buffer is something that has yet to be "written" to disk. A cache is something that has been "read" from the disk and stored for later use. 
  
但事实上:  
  1. 由于linux使用了页回写技术,所以现在page cache也起到了buffer类似的作用:先把数据写到page cache中并置为"dirty",后台进程在适当的时间再把它冲刷到磁盘上。
  2. 既然两者的角色很模糊,所以在linux2.4以后,两者在内存里是同一块区域。在2.4之间,数据会被缓存两次,浪费内存;2.4以后,数据只会缓存一次了。不过,buffer的概念仍然保留着,shell中使用free命令仍然能看到buffer项的存在。

buffer与cache操作的对象就不一样。  

buffer(缓冲)是为了提高内存和硬盘(或其他I/0设备)之间的数据交换的速度而设计的。  
cache(缓存)是为了提高cpu和内存之间的数据交换速度而设计,也就是平常见到的一级缓存、二级缓存、三级缓存。  
cpu在执行程序所用的指令和读数据都是针对内存的,也就是从内存中取得的。由于内存读写速度慢,为了提高cpu和内存之间数据交换的速度,在cpu和内存之间增加了cache,它的速度比内存快,但是造价高,又由于在cpu内不能集成太多集成电路,所以一般cache比较小,以后intel等公司为了进一步提高速度,又增加了二级cache,甚至三级cache,它是根据 程序的局部性原理 而设计的,就是cpu执行的指令和访问的数据往往在集中的某一块,所以把这块内容放入cache后,cpu就不用在访问内存了,这就提高了访问速度。当然若cache中没有cpu所需要的内容,还是要 访问 内存的。  
缓冲(buffers)是根据磁盘的读写设计的,把分散的写操作集中进行,减少磁盘碎片和硬盘的反复寻道,从而提高系统性能。linux有一个守护进程定期清空缓冲内容(即写入磁盘),也可以通过sync命令手动清空缓冲。举个例子吧:我这里有一个ext2的U盘,我往里面cp一个3M的MP3,但U盘的灯没有跳动,过了一会儿(或者手动输入sync)U盘的灯就跳动起来了。卸载设备时会清空缓冲,所以有些时候卸载一个设备时要等上几秒钟。  
修改/etc/sysctl.conf中的vm.swappiness右边的数字可以在下次开机时调节swap使用策略。该数字范围是0~100,数字越大越倾向于使用swap。默认为60,可以改一下试试。--两者都是RAM中的数据。  
简单来说,buffer是即将要被写入磁盘的,而cache是被从磁盘中读出来的。  
buffer是由各种进程分配的,被用在如输入 队列 等方面。一个简单的例子如某个进程要求有多个字段读入,在所有字段被读入完整之前,进程把先前读入的字段放在buffer中保存。  

cache经常被用在磁盘的I/O请求上,如果有多个进程都要访问某个文件,于是该文件便被做成cache以方便下次被访问,这样可提高系统性能。  

Page cache和buffer cache一直以来是两个比较容易混淆的概念,在网上也有很多人在争辩和猜想这两个cache到底有什么区别,讨论到最后也一直没有一个统一和正确的结论,在我工作的这一段时间,page cache和buffer cache的概念曾经困扰过我,但是仔细分析一下,这两个概念实际上非常的清晰。如果能够了解到这两个cache的本质,那么我们在分析io问题的时候可能会更加得心应手。


  Page cache实际上是针对文件系统的,是文件的缓存,在文件层面上的数据会缓存到page cache。文件的逻辑层需要映射到实际的物理磁盘,这种映射关系由文件系统来完成。当page cache的数据需要刷新时,page cache中的数据交给buffer cache,但是这种处理在2.6版本的内核之后就变的很简单了,没有真正意义上的cache操作。


  Buffer cache是针对磁盘块的缓存,也就是在没有文件系统的情况下,直接对磁盘进行操作的数据会缓存到buffer cache中,例如,文件系统的元数据都会缓存到buffer cache中。


  简单说来,page cache用来缓存文件数据,buffer cache用来缓存磁盘数据。在有文件系统的情况下,对文件操作,那么数据会缓存到page cache,如果直接采用dd等工具对磁盘进行读写,那么数据会缓存到buffer cache。


  补充一点,在文件系统层每个设备都会分配一个def_blk_ops的文件操作方法,这是设备的操作方法,在每个设备的inode下面会存在一个radix tree,这个radix tree下面将会放置缓存数据的page页。这个page的数量将会在top程序的buffer一栏中显示。如果设备做了文件系统,那么会生成一个inode,这个inode会分配ext3_ops之类的操作方法,这些方法是文件系统的方法,在这个inode下面同样存在一个radix tree,这里会缓存文件的page页,缓存页的数量在top程序的cache一栏进行统计。从上面的分析可以看出,2.6内核中的buffer cache和page cache在处理上是保持一致的,但是存在概念上的差别,page cache针对文件的cache,buffer是针对磁盘块数据的cache,仅此而已。


原文出自【比特网】,转载请保留原文链接:http://soft.chinabyte.com/os/50/12301550.shtml

高速缓冲存储器Cache)是一种位于主存CPU之间的高速存储器,其主要目的是提高数据访问速度,减少CPU等待时间,从而提升整体系统性能。以下是关于高速缓冲存储器的原理、应用及工作机制的详细介绍。 ### 原理 高速缓冲存储器的工作原理基于程序执行的局部性原理,主要包括时间局部性空间局部性。时间局部性指的是如果一个数据被访问了一次,那么在不久的将来它很可能再次被访问;空间局部性指的是如果一个数据被访问了,那么其邻近的数据也可能很快被访问。基于这一原理,Cache会将最近访问的数据或与当前访问数据相邻的数据存储在其内部,以便下次访问时能够快速获取[^1]。 Cache的容量通常远小于主存,但其访问速度接近CPU的速度。为了缓解容量、速度成本之间的矛盾,计算机系统采用了多层次的存储体系结构,其中Cache位于主存之上,形成Cache-主存层次。这一层次的存取速度接近于Cache的速度,而容量接近于主存的容量,从而解决了高速存取低成本之间的矛盾。 ### 应用 高速缓冲存储器广泛应用于现代计算机系统中,尤其是在CPU内部或靠近CPU的位置。常见的应用包括: - **指令缓存**:用于缓存即将执行的指令。 - **数据缓存**:用于缓存CPU需要处理的数据。 - **统一缓存**:同时缓存指令数据。 此外,Cache还被用于其他领域,如图形处理器(GPU)、网络设备嵌入式系统中,以提高数据处理效率[^2]。 ### 工作机制 高速缓冲存储器的工作机制涉及多个方面,包括映射方式、替换策略写策略。 #### 映射方式 Cache与主存之间的映射方式决定了主存中的数据如何被加载到Cache中。常见的映射方式包括: - **直接映射**:每个主存块只能映射到Cache中的一个特定位置。 - **全相连映射**:每个主存块可以映射到Cache中的任意位置。 - **组相连映射**:结合了直接映射全相连映射的优点,将Cache分成若干组,每组包含多个块,主存块可以映射到某一组内的任意位置。 不同的映射方式会影响Cache的命中率复杂度。例如,在全相连映射中,虽然命中率较高,但由于需要比较所有Cache块,因此硬件复杂度也较高[^5]。 #### 替换策略 当Cache已满且需要加载新的数据块时,必须选择一个现有的块进行替换。常见的替换策略包括: - **最近最少使用(LRU)**:替换最近最少使用的块。 - **先进先出(FIFO)**:替换最早进入Cache的块。 - **随机替换(Random)**:随机选择一个块进行替换。 这些策略各有优劣,LRU通常能提供较高的命中率,但实现成本较高;而FIFO随机替换则相对简单,但在某些情况下可能不如LRU有效。 #### 写策略 当CPU对Cache进行写操作时,需要考虑如何将数据写入主存。常见的写策略包括: - **全写法(Write Through)**:每次写操作都会同时更新Cache主存。这种方式保证了数据的一致性,但可能会影响性能。 - **写回法(Write Back)**:仅在Cache中更新数据,只有当该数据被替换出Cache时才写回主存。这种方式减少了对主存的写操作,提高了性能,但需要额外的机制来跟踪哪些数据是脏的(即已修改但未写回主存)。 为了缓解全写法带来的性能瓶颈,通常会在Cache主存之间引入一个写缓冲(Write Buffer)。CPU在执行写操作时,只需将数据写入Cache写缓冲即可继续执行后续指令,由写缓冲异步地将数据写入主存。写缓冲通常采用FIFO队列结构,以协调Cache与主存之间的速度差异[^3]。 ### 示例代码 以下是一个简单的Cache模拟器的Python代码片段,展示了Cache的基本操作,包括读取写入: ```python class Cache: def __init__(self, size, block_size): self.size = size self.block_size = block_size self.cache = {} def read(self, address): # 计算块号 block_number = address // self.block_size if block_number in self.cache: print(f"Cache hit for block {block_number}") return self.cache[block_number] else: print(f"Cache miss for block {block_number}") # 模拟从主存加载数据 data = self._load_from_memory(block_number) self.cache[block_number] = data return data def write(self, address, data): # 计算块号 block_number = address // self.block_size # 更新Cache self.cache[block_number] = data # 模拟写入主存(全写法) self._write_to_memory(block_number, data) def _load_from_memory(self, block_number): # 模拟从主存加载数据 print(f"Loading block {block_number} from main memory") return f"data_{block_number}" def _write_to_memory(self, block_number, data): # 模拟写入主存 print(f"Writing block {block_number} to main memory with data {data}") # 使用示例 cache = Cache(size=4, block_size=16) cache.read(0) # 第一次读取,Cache未命中 cache.read(0) # 第二次读取,Cache命中 cache.write(0, "new_data_0") # 写入操作 ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值