cache是什么文件

cache是什么文件

这个文件夹是临时缓存文件夹,很多软件启动之后都会在这个文件夹里放一些缓存文件。这个很正常。记得经常清除这个文件夹里的文件。时间长了会有很多垃圾。

有这个缓存,会对你浏览和玩的速度提升!好的!

但是时间久了,需要删除!

他还会自动建立的!

linux内核之内存管理

Linux内核之内存管理 作者:harvey wang 邮箱:harvey.perfect@https://www.360docs.net/doc/df11048980.html, 新浪博客地址:https://www.360docs.net/doc/df11048980.html,/harveyperfect,有关于减肥和学习英语相关的博文,欢迎交流 把linux内存管理分为下面四个层面 (一)硬件辅助的虚实地址转换 (二)内核管理的内存相关 (三)单个进程的内存管理 (四)malloc软件 (一)处理器硬件辅助的虚实地址转换(以x86为例) 在x86中虚实地址转换分为段式转换和页转换。段转换过程是由逻辑地址(或称为虚拟地址)转换为线性地址;页转换过程则是将线性地址转换为物理地址。段转换示意图如下 X86支持两种段,gdt和ldt(全局描述段表和局部描述符段表),在linux中只使用了4个全局描述符表,内核空间和用户空间分别两个gdt,分别对应各自的代码段和数据段。也可以认为在linux中变相地disable了x86的段式转换功能。 页转换示意图如下

在linux中x86 的cr3寄存器(页表基地址寄存器)保存在进程的上下文中,在进程切换时会保存或回复该寄存器的内容,这样每个进程都有自己的转换页表,从而保证了每个进程有自己的虚拟空间。 (二)内核管理的内存相关 从几个概念展开内存管理:node、zone、buddy、slab 1、Node SGI Altix3000系统的两个结点 如上图,NUMA系统的结点通常是由一组CPU(如,SGI Altix 3000是2个Itanium2 CPU)和本地内存组成。由于每个结点都有自己的本地内存,因此全系统的内存在物理上是分布的,每个结点访问本地内存和访问其它结点的远地内存的延迟是不同的,为了优化对NUMA 系统的支持,引进了Node 来将NUMA 物理内存进行划分为不同的Node。而操作系统也必须能感知硬件的拓扑结构,优化系统的访存。

Cache的工作原理

前言 虽然CPU主频的提升会带动系统性能的改善,但系统性能的提高不仅仅取决于CPU,还与系统架构、指令结构、信息在各个部件之间的传送速度及存储部件的存取速度等因素有关,特别是与CPU/内存之间的存取速度有关。 若CPU工作速度较高,但内存存取速度相对较低,则造成CPU等待,降低处理速度,浪费CPU的能力。 如500MHz的PⅢ,一次指令执行时间为2ns,与其相配的内存(SDRAM)存取时间为10ns,比前者慢5倍,CPU和PC的性能怎么发挥出来? 如何减少CPU与内存之间的速度差异?有4种办法: 一种是在基本总线周期中插入等待,但这样会浪费CPU的能力。 另一种方法是采用存取时间较快的SRAM作存储器,这样虽然解决了CPU与存储器间速度不匹配的问题,但却大幅提升了系统成本。 第3种方法是在慢速的DRAM和快速CPU之间插入一速度较快、容量较小的SRAM,起到缓冲作用;使CPU既可以以较快速度存取SRAM中的数据,又不使系统成本上升过高,这就是Cache法。 还有一种方法,采用新型存储器。 目前,一般采用第3种方法。它是PC系统在不大增加成本的前提下,使性能提升的一个非常有效的技术。 本文简介了Cache的概念、原理、结构设计以及在PC及CPU中的实现。 Cache的工作原理 Cache的工作原理是基于程序访问的局部性。 对大量典型程序运行情况的分析结果表明,在一个较短的时间间隔内,由程序产生的地址往往集中在存储器逻辑地址空间的很小范围内。指令地址的分布本来

就是连续的,再加上循环程序段和子程序段要重复执行多次。因此,对这些地址的访问就自然地具有时间上集中分布的倾向。 数据分布的这种集中倾向不如指令明显,但对数组的存储和访问以及工作单元的选择都可以使存储器地址相对集中。这种对局部范围的存储器地址频繁访问,而对此范围以外的地址则访问甚少的现象,就称为程序访问的局部性。 根据程序的局部性原理,可以在主存和CPU通用寄存器之间设置一个高速的容量相对较小的存储器,把正在执行的指令地址附近的一部分指令或数据从主存调入这个存储器,供CPU在一段时间内使用。这对提高程序的运行速度有很大的作用。这个介于主存和CPU之间的高速小容量存储器称作高速缓冲存储器(Cache)。 系统正是依据此原理,不断地将与当前指令集相关联的一个不太大的后继指令集从内存读到Cache,然后再与CPU高速传送,从而达到速度匹配。 CPU对存储器进行数据请求时,通常先访问Cache。由于局部性原理不能保证所请求的数据百分之百地在Cache中,这里便存在一个命中率。即CPU在任一时刻从Cache中可靠获取数据的几率。 命中率越高,正确获取数据的可靠性就越大。一般来说,Cache的存储容量比主存的容量小得多,但不能太小,太小会使命中率太低;也没有必要过大,过大不仅会增加成本,而且当容量超过一定值后,命中率随容量的增加将不会有明显地增长。 只要Cache的空间与主存空间在一定范围内保持适当比例的映射关系,Cache 的命中率还是相当高的。 一般规定Cache与内存的空间比为4:1000,即128kB Cache可映射32MB内存;256kB Cache可映射64MB内存。在这种情况下,命中率都在90%以上。至于没有命中的数据,CPU只好直接从内存获取。获取的同时,也把它拷进Cache,以备下次访问。

Cache 管理

1 前言 自从诞生以来,Linux 就被不断完善和普及,目前它已经成为主流通用操作系统之一,使用得非常广泛,它与Windows、UNIX 一起占据了操作系统领域几乎所有的市场份额。特别是在高性能计算领域,Linux 已经成为一个占主导地位的操作系统,在2005年6月全球TOP500 计算机中,有301 台部署的是Linux 操作系统。因此,研究和使用Linux 已经成为开发者的不可回避的问题了。 下面我们介绍一下Linux 内核中文件Cache 管理的机制。本文以 2.6 系列内核为基准,主要讲述工作原理、数据结构和算法,不涉及具体代码。 2 操作系统和文件Cache 管理 操作系统是计算机上最重要的系统软件,它负责管理各种物理资源,并向应用程序提供各种抽象接口以便其使用这些物理资源。从应用程序的角度看,操作系统提供了一个统一的虚拟机,在该虚拟机中没有各种机器的具体细节,只有进程、文件、地址空间以及进程间通信等逻辑概念。这种抽象虚拟机使得应用程序的开发变得相对容易:开发者只需与虚拟机中的各种逻辑对象交互,而不需要了解各种机器的具体细节。此外,这些抽象的逻辑对象使得操作系统能够很容易隔离并保护各个应用程序。 对于存储设备上的数据,操作系统向应用程序提供的逻辑概念就是"文件"。应用程序要存储或访问数据时,只需读或者写"文件"的一维地址空间即可,而这个地址空间与存储设备上存储块之间的对应关系则由操作系统维护。 在Linux 操作系统中,当应用程序需要读取文件中的数据时,操作系统先分配一些内存,将数据从存储设备读入到这些内存中,然后再将数据分发给应用程序;当需要往文件中写数据时,操作系统先分配内存接收用户数据,然后再将数据从内存写到磁盘上。文件Cache 管理指的就是对这些由操作系统分配,并用来存储文件数据的内存的管理。Cache 管理的优劣通过两个指标衡量:一是Cache 命中率,Cache 命中时数据可以直接从内存中获取,不再需要访问低速外设,因而可以显著提高性能;二是有效Cache 的比率,有效Cache 是指真正会被访问到的Cache 项,如果有效Cache 的比率偏低,则相当部分磁盘带宽会被浪费到读取无用Cache 上,而且无用Cache 会间接导致系统内存紧张,最后可能会严重影响性能。 下面分别介绍文件Cache 管理在Linux 操作系统中的地位和作用、Linux 中文件Cache 相关的数据结构、Linux 中文件Cache 的预读和替换、Linux 中文件Cache 相关API 及其实现。 2 文件Cache 的地位和作用 文件Cache 是文件数据在内存中的副本,因此文件Cache 管理与内存管理系统和文件系统都相关:一方面文件Cache 作为物理内存的一部分,需要参与物理内存的分配回收过程,另一方面文件Cache 中的数据来源于存储设备上的文件,需要通过文件系统与存储设备进行读写交互。从操作系统的角度考虑,文件Cache 可以看做是内存管理系统与文件系统之间的联系纽带。因此,文件Cache 管理是操作系统的一个重要组成部分,它的性能直接影响着文件系统和内存管理系统的性能。 图1描述了Linux 操作系统中文件Cache 管理与内存管理以及文件系统的关系示意图。从图中可以看到,在Linux 中,具体文件系统,如ext2/ext3、jfs、ntfs 等,负责在文件Cache 和存储设备之间交换数据,位于具体文件系统之上的虚拟文件系统VFS负责在应用程序和文件Cache 之间通过read/write 等接口交换数据,而内存管理系统负责文件Cache 的分配和回收,同时虚拟内存管理系统(VMM)则允许应用程序和文件Cache 之间通过memory

缓存框架所要解决的基本问题

缓存框架所要解决的基本问题

Cache 框架,顾名思义即数据的暂存场所和管理。那么该系统的两个核心功能就开始上演了,即存放数据的一个容器和管理缓存容器。就像数据库服务器软件一样,他有一个和新的数据存放场所,同时还有一个管理数据的管理系统。在这个管理系统中就出现了一系列的事务处理,比如说添加,删除,更新以及刷新,删除不成功时如何操作等等。那么该缓存框架需要完成的基本任务就是如何来实例化这么一个数据存储的仓库以及如何有效的来管理仓库中的这些数据,除了上述的这些操作外,还有当仓库中的数据当容量值是再次放入一个缓存实体时该如何有效的淘汰已存在的缓存实体以及该缓存仓库中的数据是否持久有效还是分区管理等等。那么又该如何实例化这么一个缓存仓库呢?首先要考虑的第一问题就是采用何种数据结构来高效的存储这些数据? 1、如何来管理缓存中的对象?----OScache中是通过AbstractConcurrentReadCache和Cache强强联手来管理的 2、如何来管理内存容量的问题? 3、给缓存中添加一个新的缓存实体时,需要注意哪些问题? 当向缓存中添加一个实体时,应该完成哪些必要的业务逻辑呢?我们可以把缓存看做是一个组件,添加一个新的实体是促发该组件的一个事件,该组件能够对该事件进行捕捉并能够进行相应的处理。 4、如何有效的来淘汰缓冲池中对象? 5、如何来管理缓存实体的刷新问题? 实体的更新状态信息具体分应该分为以下几种:分别是还没更新、处于更新状态中、更新完成、更新取消。其中用一个变量来保存当前的更新状态,也即跟踪每一个缓存缓存对象当前处于一种什么状态。同时用什么来表明一个缓存实体过期的标识呢?这里有两种方案:其一就是线程拥有的数量,当线程拥有的数量变为0时,就从缓存容器中释放。其二就是设置一个TTL 发呆的最大

TCP的发送系列 — 发送缓存的管理(一)

TCP的发送系列—发送缓存的管理(一) 数据结构 TCP对发送缓存的管理是在两个层面上进行的,一个层面是单个socket的发送缓存管理, 另一个层面是整个TCP层的内存管理。 单个socket的发送缓存所涉及的变量。 [java] struct sock { ... /* 预分配缓存大小,是已经分配但尚未使用的部分 */ int sk_forward_alloc; ... /* 提交给IP层的发送数据大小(累加skb->truesize) */ atomic_t sk_wmem_alloc; ... int sk_sndbuf; /* 发送缓冲区大小的上限 */ struct sk_buff_head sk_write_queue; /* 发送队列 */ ... /* 发送队列的总大小,包含发送队列中skb负荷大小, * 以及sk_buff、sk_shared_info结构体、协议头的额外开销。 */

int sk_wmem_queued; ... }; 整个TCP层的内存相关变量。 [java] struct proto tcp_prot = { .name = "TCP", .owner = THIS_MODULE, ... /* 设置TCP的内存压力标志,把tcp_memory_pressure置为1 */ .enter_memory_pressure = tcp_enter_memory_pressure, /* 检查sock是否有剩余的发送缓存(sk_wmem_queued < sk_sndbuf)。 * 值得注意的是,用户可以使用TCP_NOTSENT_LOWAT选项来避免占用过多的发送缓存。 */ .stream_memory_free = tcp_stream_memory_free, ... /* TCP目前已经分配的内存 */ .memory_allocated = &tcp_memory_allocated, /* TCP内存压力标志,超过tcp_mem[1]后设置,低于tcp_mem[0]后清除 */ .memory_pressure = &tcp_memory_pressure, /* TCP内存使用的最小值、压力值、最大值,单位为页 */

Linux内核的页缓存概述

Linux内核的页缓存概述 页缓存是Linux内核一种重要的磁盘高速缓存,它通过软件机制实现。但页缓存和硬件cache的原理基本相同,将容量大而低速设备中的部分数据存放到容量小而快速的设备中,这样速度快的设备将作为低速设备的缓存,当访问低速设备中的数据时,可以直接从缓存中获取数据而不需再访问低速设备,从而节省了整体的访问时间。 页缓存以页为大小进行数据缓存,它将磁盘中最常用和最重要的数据存放到部分物理内存中,使得系统访问块设备时可以直接从主存中获取块设备数据,而不需从磁盘中获取数据。 在大多数情况下,内核在读写磁盘时都会使用页缓存。内核在读文件时,首先在已有的页缓存中查找所读取的数据是否已经存在。如果该页缓存不存在,则一个新的页将被添加到高速缓存中,然后用从磁盘读取的数据填充它。如果当前物理内存足够空闲,那么该页将长期保留在高速缓存中,使得其他进程再使用该页中的数据时不再访问磁盘。写操作与读操作时类似,直接在页缓存中修改数据,但是页缓存中修改的数据(该页此时被称为Dirty Page)并不是马上就被写入磁盘,而是延迟几秒钟,以防止进程对该页缓存中的数据再次修改。 页缓存的设计需求 页缓存至少需要满足以下两种需求。首先,它必须可以快速定位含有给定数据的特定页。其次,由于页高速缓存中的数据来源不同,比如普通文件、块设备等,内核必须根据不同的数据来源来选择对页缓存的适当操作。

内核通过抽象出address_space数据结构来满足上述两种设计需求。address_space结构 address_space 结构是页高速缓存机制中的核心数据结构,该结构并不是对某一个页高速缓存进行描述,而是以页高速缓存的所有者(owner)为单位,对其所拥有的缓存进行抽象描述。页高速缓存中每个页包含的数据肯定属于某个文件,该文件对应的inode对象就称为页高速缓存的所有者。 页缓存与文件系统和内存管理都有联系。每个inode结构中都嵌套一个address_space结构,即inode字段中的i_data;同时inode中还有i_maping 字段指向所嵌套address_spaces结构。而address_space结构通过host字段反指向页高速缓存的所有者。页缓存的本质就是一个物理页框,因此每个页描述符中通过mmaping和index两个字段与高速缓存进行关联。mmaping指向页缓存所有者中的address_space对象。index表示以页大小为单位的偏移量,该偏移量表示页框内数据在磁盘文件中的偏移量。 address_space 结构中的i_mmap字段指向一个radix优先搜索树。该树将一个文件所有者中的所有页缓存组织在一起,这样可以快速搜索到指定的页缓存。内核中关于radix树有一套标准的使用方法,它不与特定的数据联系(与内核双联表类似),这样使得使用范围更加灵活。具体操作如下: radix_tree_lookup():在radix树中对指定节点进行查找; radix_tree_insert():在radix树中插入新节点;

内核启动流程分析

linux内核的启动过程: 在bootloader将linux内核映像拷贝到RAM以后,启动linux内核: call_linux(0,machine_type, kernel_params_base)。 其中,machine_tpye是bootloader检测出来的处理器类型,kernel_params_base 是启动参数在RAM的地址。通过这种方式将Linux启动需要的参数从bootloader传递到内核。 linux内核有两种映像:一种是非压缩内核,叫Image,另一种是它的压缩版本,叫zImage。根据内核映像的不同,linux内核的启动在开始阶段也有所不同。zImage是Image经过压缩形成的,所以它的大小比Image小。但为了能使用zImage,必须在它的开头加上解压缩的代码,将zImage解压缩之后才能执行, 因此它的执行速度比Image要慢。但考虑到嵌入式系统的存储空容量一般比较小,采用zImage可以占用较少的存储空间,因此牺牲一点性能上的代价也是值得的。所以一般的嵌入式系统均采用压缩内核的方式。 对于ARM系列处理器来说,zImage的入口程序即为 arch/arm/boot/compressed/head.s。它依次完成一下工作:开启MMU和cache,调用decompress_kernel()解压内核,最后通过调用call_kernel()进入非压缩内核Image的启动。下面将具体分析在此之后Linux内核的启动过程。 2:linux内核入口 Linux非压缩内核的入口位于文件/arch/arm/kernel/head-armv.S中的stext段。该段的基地址就是压缩内核解压后的跳转地址。如果系统中加载的内核是非压缩的Image,那么bootloader将内核从Flash中拷贝到RAM后将直接跳到该地址处,从而启动Linux内核。不同体系结构的Linux系统的入口文件是不同的,而且因为该文件与具体体系结构有关,所以一般均用汇编语言编写[3]。对基于ARM处理的Linux系统来说,该文件就是head-armv.S。该程序通过查找处理器内核类 型和处理器类型调用相应的初始化函数,再建立页表,最后跳转到start_kernel()函数开始内核的初始化工作。 检测处理器内核类型是在汇编子函数__lookup_processor_type中完成的。通过以下代码可实现对它的调用:bl__lookup_processor_type。__lookup_processor_type 调用结束返回原程序时,会将返回结果保存到寄存器中。其中r8保存了页表的 标志位,r9保存了处理器的ID号,r10保存了与处理器相关的struproc_info_list 结构地址。 检测处理器类型是在汇编子函数__lookup_architecture_type中完成的。与 __lookup_processor_type类似,它通过代码:“bl__lookup_processor_type”来实现 对它的调用。该函数返回时,会将返回结构保存在r5、r6和r7三个寄存器中。其中r5保存了RAM的起始基地址,r6保存了I/O基地址,r7保存了I/O的页表偏移地址。当检测处理器内核和处理器类型结束后,将调用__create_page_tables 子函数来建立页表,它所要做的工作就是将RAM基地址开始的4M空间的物理地址映射到0xC0000000开始的虚拟地址处。对笔者的S3C2410开发板而言,RAM连接到物理地址0x30000000处,当调用__create_page_tables结束后 0x30000000~0x30400000物理地址将映射到0xC0000000~0xC0400000虚拟地址处。

Java 中常用缓存Cache机制的实现

Cache 所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。 缓存主要可分为二大类: 一、通过文件缓存,顾名思义文件缓存是指把数据存储在磁盘上,不管你是以XML格式,序列化文件DAT格式还是其它文件格式; 二、内存缓存,也就是实现一个类中静态Map,对这个Map进行常规的增删查. 代码如下: package lhm.hcy.guge.frameset.cache; import java.util.*; //Description: 管理缓存 //可扩展的功能:当chche到内存溢出时必须清除掉最早期的一些缓存对象,这就要求对每个缓存对象保存创建时间 public class CacheManager { private static HashMap cacheMap = new HashMap(); //单实例构造方法 private CacheManager() { super(); } //获取布尔值的缓存 public static boolean getSimpleFlag(String key){ try{ return (Boolean) cacheMap.get(key); }catch(NullPointerException e){ return false;

} public static long getServerStartdt(String key){ try { return (Long)cacheMap.get(key); } catch (Exception ex) { return 0; } } //设置布尔值的缓存 public synchronized static boolean setSimpleFlag(String key,boolean flag){ if (flag && getSimpleFlag(key)) {//假如为真不允许被覆盖 return false; }else{ cacheMap.put(key, flag); return true; } } public synchronized static boolean setSimpleFlag(String key,long serverbegrundt){ if (cacheMap.get(key) == null) { cacheMap.put(key,serverbegrundt); return true; }else{ return false; } } //得到缓存。同步静态方法 private synchronized static Cache getCache(String key) { return (Cache) cacheMap.get(key); } //判断是否存在一个缓存 private synchronized static boolean hasCache(String key) { return cacheMap.containsKey(key); } //清除所有缓存 public synchronized static void clearAll() { cacheMap.clear(); } //清除某一类特定缓存,通过遍历HASHMAP下的所有对象,来判断它的KEY与传入的

ARM920T的MMU与Cache(整理版)

ARM920T的MMU与Cache 宋劲杉 原文来源——https://www.360docs.net/doc/df11048980.html,/pages/news_detail.php?id=374&page=2 目录 虚拟地址和物理地址的概念 虚拟内存管理 ARM920T的CP15协处理器 MMU Cache 操作MMU和Cache的内核启动代码 参考资料 索引 虚拟地址和物理地址的概念 CPU通过地址来访问内存中的单元,地址有虚拟地址和物理地址之分,如 果CPU没有MMU(Memory Management Unit,内存管理单元),或者有MMU 但没有启用,CPU核在取指令或访问内存时发出的地址将直接传到CPU芯片的外部地址引脚上,直接被内存芯片(以下称为物理内存,以便与虚拟内存区分)接收,这称为物理地址(Physical Address,以下简称PA),如下图所示。 图 1. 物理地址示意图 如果CPU启用了MMU,CPU核发出的地址将被MMU截获,从CPU到MMU的地址称为虚拟地址(Virtual Address,以下简称VA),而MMU将这个

地址翻译成另一个地址发到CPU芯片的外部地址引脚上,也就是将虚拟地址映射成物理地址,如下图所示[1]。 图 2. 虚拟地址示意图 MMU将虚拟地址映射到物理地址是以页(Page)为单位的,对于32位CPU 通常一页为4K。例如,虚拟地址0xb700 1000~0xb700 1fff是一个页,可能被MMU映射到物理地址0x2000~0x2fff,物理内存中的一个物理页面也称为一个页框(Page Frame)。 虚拟内存管理 现代操作系统充分利用MMU提供的VA到PA的映射机制来做内存管理,以下称为虚拟内存管理(Virtual Memory Management)。首先看下面的例子:

linux启动--文件系统初始化

Linux启动--vfs相关初始化 内核在启动时对文件系统的初始化,主要完成的工作是为vfs中各种数据结构申请缓存,初始化散列表,并加载rootfs作为当前进程的根文件系统。 1、start_kernel( )中与文件系统相关的初始化 start_kernel( ) { ... vfs_caches_init_early(); //fs/dcache.c完成dentry,inode散列表的初始化。 .... vfs_caches_init(); //fs/dcache.c .... proc_root_init(); nsfs_init(); ... } 本节对上面函数逐一进行分析。 2、vfs_caches_init_early( ) // fs/dcache.c void __init vfs_caches_init_early(void) { dcache_init_early(); inode_init_early(); } dcache_init_early()在fs/dcache.c中主要完成目录结构dentry的散列表初始化。 inode_init_early()在fs/inode.c中主要完成inode结构散列表的初始化。 3 、vfs_caches_init( ) 此函数在fs/dcache.c是文件系统初始化的主要函数。 void __init vfs_caches_init(void) { names_cachep = kmem_cache_create("names_cache", P ATH_MAX, 0, SLAB_HWCACHE_ALIGN|SLAB_P ANIC, NULL); dcache_init(); //fs/dcache.c inode_init(); //fs/inode.c files_init(); //fs/file_table.c

Linux 内存管理导读

Linux 内存管理导读 1. 存储层次结构和x86存储管理硬件(MMU) 1.1存储层次 高速缓存(cache) à主存(main memory) à磁盘(disk) 理解存储层次结构的根源:CPU速度和存储器速度的差距。 层次结构可行的原因:局部性原理。 LINUX的任务: l减小footprint,提高cache命中率,充分利用局部性。 l实现虚拟存储以满足进程的需求,有效地管理内存分配,力求最合理地利用有限的资源。 1.2 MMU的作用 辅助操作系统进行内存管理,提供虚实地址转换等硬件支持。 1.3 x86的地址 逻辑地址:出现在机器指令中,用来制定操作数的地址。段:偏移 线性地址:逻辑地址经过分段单元处理后(如将段地址左移四位与偏移量)得到线性地址,这是一个32位的无符号整数,可用于定位4G个存储单元。 物理地址:线性地址经过页表查找后得出物理地址,这个地址将被送到地址总线上指示所要访问的物理内存单元。 LINUX: 尽量避免使用段功能以提高可移植性。如通过使用基址为0的段, 使逻辑地址==线性地址。 1.4 x86的段与Linux下的段比较 x86保护模式下的段:表索引+描述符项。不仅仅是一个基地址的原因是为了提供更多的信息:保护、长度限制、类型等。描述符项存放在一张表中(GDT或LDT),表索引就是表的索引。段寄存器中存放的是表索引,在段寄存器装入的同时,描述符中的数据被装入一个不可见的寄存器以便cpu快速访问。 专用寄存器:GDTR(包含全局描述附表的首地址), LDTR(当前进程的段描述附表首地址), TSR(指向当前进程的任务状态段) LINUX使用的四种段: __KERNEL_CS:内核代码段。范围0-4G。可读、执行。DPL=0。 __KERNEL_DS:内核代码段。范围0-4G。可读、写。DPL=0。 __USER_CS:内核代码段。范围0-4G。可读、执行。DPL=3。 __USER_DS:内核代码段。范围0-4G。可读、写。DPL=3。 TSS(任务状态段):存储进程的硬件上下文,进程切换时使用。(因为x86硬件对TSS有一定支持,所有有这个特殊的段和相应的专用寄存器。) __USER_CS和__USER_DS段都是被所有在用户态下的进程共享的。但这种段的共享和进程空间的共享是有区别的:虽然各个进程使用同一个(种)段,但通过使

LINUX操作系统缓存机制之页缓存

list; /* ditto */ /*指向相关的地址空间的指针*/ struct address_space *assoc_mappi ng; /* ditto */ }__attribute__(( aligned(siz struct backing_dev_info { struct list_head bdi_list;struct rcu_head rcu_head;/*最大预读数量,单位为page _cache_size*/unsigned long ra_pages; es;/* device capabilities */ congested_fn *congested_fn; /* function pointer if device is md/dm */ void *congested_data; /* pointer to aux data for congested func */ void (*unplug_io_fn)(struct backing_dev_info *,struct page *);void *unplug_io_data; char *name; struct percpu_counter bdi_stat[nr_bdi_stat_items]; unsigned int min_ratio;unsigned int max_ratio, max_prop_frac; struct device *dev; #ifdef config_debug_fs struct dentry *debug_dir;struct dentry *debug_stats;#endif };下图为地址空间与内核其他部分的关联。 内核采用一种通用的地址空间方案,来建立缓存数据与其来源之间的关联。 1)内存中的页分配到每个地址空间。这些页的内容可以由用户进程或内核本身使用各式各样的方法操作。这些数据表示了缓存中的内容;2)后备存储器struct backing_dev_info 指定了填充地址空间中页的数据的来源。地址空间关联到处理器的虚拟地址空间,是由处理器在虚拟内存中管理的一个区域到设备device上对应位置之间的一个映射。 如果访问了虚拟内存中的某个位置,该位置没有关联到物理内存页,内核可根据地址空间结构来找到读取数据的来源。 为支持数据传输,每个地址空间都提供了一组操作,以容许地址空间所涉及双方面的交互。 地址空间是内核中最关键的数据结构之一,对该数据结构的管理,已经演变为内核面对的最关键的问题之一。页缓存的任务在于,获得一些物理内存页,以加速在块设备上按页为单位执行的操作。 内核使用了基数树来管理与一个地址空间相关的所有页,以便尽可能降低开销。

MMU与CACHE详解

ARM920T的MMU与Cache 目录 虚拟地址和物理地址的概念 虚拟内存管理 ARM920T的CP15协处理器 MMU Cache 操作MMU和Cache的内核启动代码 参考资料索引 虚拟地址和物理地址的概念 CPU通过地址来访问内存中的单元,地址有虚拟地址和物理地址之分,如果CPU没有MMU (Memory Management Unit,内存管理单元),或者有MMU但没有启用,CPU核在取指令或访问内存时发出的地址将直接传到CPU芯片的外部地址引脚上,直接被内存芯片(以下称为物理内存,以便与虚拟内存区分)接收,这称为物理地址(Physical Address,以下简称PA),如下图所示。 图 1. 物理地址示意图 如果CPU启用了MMU,CPU核发出的地址将被MMU截获,从CPU到MMU的地址称为虚拟地址(Virtual Address,以下简称VA),而MMU将这个地址翻译成另一个地址发到CPU芯片的外部地址引脚上,也就是将虚拟地址映射成物理地址,如下图所示[1]。

图 2. 虚拟地址示意图 MMU将虚拟地址映射到物理地址是以页(Page)为单位的,对于32位CPU 通常一页为4K。例如,虚拟地址0xb700 1000~0xb700 1fff是一个页,可能被MMU映射到物理地址0x2000~0x2fff,物理内存中的一个物理页面也称为一个页框(Page Frame)。 虚拟内存管理 现代操作系统充分利用MMU提供的VA到PA的映射机制来做内存管理,以下称为虚拟内存管理(Virtual Memory Management)。首先看下面的例子: 例 1. 进程的地址空间 这是bash进程的虚拟地址空间,32位CPU的虚拟地址空间是4GB,也就是 0x0000 0000-0xffff ffff,该进程占用的地址范围近似为0x0000 0000-0xbfff ffff,地址范围0xc000 0000-0xffff ffff由内核占用,用户进程不允许访问。在这个bash进程的地址空间中,从0x0804 8000开始的668K的权限为r-x--,

当前典型多核处理器的cache结构分析

当前典型多核处理器的cache结构分析 摘要:对多核处理器发展中高速缓存 Cache 存储层所出现的问题进行分析与研究,主要是多核结构采用的多级分布式 Cache 引发的存储一致性问题。最早的NUCA研究了对单处理器环境下 NUCA 效应给处理器性能带来的影响。后来针对NUCA 提出了一种称为动态非一致性访问(Dynamic Non-Uniform Cache Access, DNUCA )的设计来管理大容量 Cache。多核架构下的另一种管理片上大容量Cache 的思路是采用分布式管理,将片上的 Cache 资源分布到各个处理器内核结点,通过设计划分强调连线的局部性,避免频繁长距离 Cache 通信的产生。 1 背景 高速缓冲存储器 Cache 是计算机存储系统中最重要的部分,最早由Wilkes 于1951 年构想出来。Cache 技术的出现正是为了弥补处理器与存贮器之间的速度差异。目前,多核处理器芯片普遍采用在片内集成大容量Cache 的方式来提高存储系统的性能。大容量 Cache 可以直接增加处理器芯片内 Cache 命中率,减少片外访存的频率,但由于 Cache 面积过大,又分散在芯片的不同位置,在线延迟的影响下,同一层次但不同距离Cache 的访问呈现出不同的通讯延迟,即所谓的非一致性缓存访问 NUCA (Non-Uniform Cache Access)。 2 多核中Cache结构综述 2.1多核芯片上的Cache技术 多处理器核组织结构主要有UCA (UniformCache Access)和NUCA (Non-Uniform Cache Access)两种(如图1所示)。在UCA结构中,多个处理器核与二级Cache通过互联总线(Bus)或交叉开关(cross switch)互联,所有处理和对二级Cache访问延迟相同;在NUCA结构中,每个处理器核具有本地二级Cache,通过互联系统对其他处理器核的二级Cache访问(延迟变长)。随着集成度的提高,也可以讲三级Cache集成到片内,如图2所示。在以上4种组织中,片内二级或三级Cache均为所有处理器核共享。 当一块芯片上集成了多个处理器核时,各个处理器核之间通过共享Cache数据单元实现数据的交换与同步,多核争用Cache中的数据是多核芯片需要解决的一个重要问题。 2.2 多核架构对处理器Cache技术的影响 最早的 NUCA研究了对单处理器环境下 NUCA 效应给处理器性能带来的影响。后来针对 NUCA 提出了一种称为动态非一致性访问(Dynamic Non-Uniform Cache Access, DNUCA )的设计来管理大容量 Cache。DNUCA 是将大容量Cache 分为很多小的Bank,允许 Cache块动态地进行物理位置上的迁移,运行时的热点数据将逐渐集中到离处理器内核较近位置的Bank 中,以此来降低访问 Cache 的延迟。

HP-UX内核管理及配置

HP-UX内核管理

目录 第1章内核管理 (3) 1.1 调整HP-UX内核参数意义 (3) 1.2 HP-UX内核参数的解释 (4) 1.2.1 记账子系统(Accounting Subsystem) (4) 1.2.2 异步IO子系统(Asynchronous I/O Subsystem) (5) 1.2.3 光纤通道子系统(FibreChannel Subsystem) (5) 1.2.4 文件子系统(File System Subsystem) (6) 1.2.5 进程间通信子系统(Interprocess Communication (IPC) Subsystem) (10) 1.2.6 内核转储子系统(Kernel Panic Dump Subsystem) (14) 1.2.7 内存分页子系统(Memory Paging Subsystem) (14) 1.2.8 . 进程管理子系统(Process Management Subsystem) (16) 1.2.9 旋转锁子系统(Spinlock Pool Subsystem) (18) 1.2.10 流子系统(Streams Subsystem) (19) 1.2.11 其他参数(Miscellaneous Parameters) (20) 1.3 调整HP-UX内核参数值和驱动方法 (23)

第1章内核管理 1.1 调整HP-UX内核参数意义 依据不同的生产情况,惠普公司提供了不同的HP-UX的安装介质。操作环境 (OE) 是经过测试并集成的应用程序软件包,用于与操作系统配合使用,并提供系统所需的功能。HP-UX 11i v1 (B.11.11) DVD 提供了下列操作环境: a)HP-UX 11i v1 Foundation OE (FOE) — 用于满足 Web 服务器、目录服务器和前端服务 器的需求,此 OE 包括多种应用程序,如 HP-UX Web 服务器套件、Java2 Standard Edition 技术和 Mozilla 应用程序套件。这种操作环境与 HP-UX 11i 捆绑在一起时称为 HPUX11i-OE b)HP-UX 11i v1 Enterprise OE (EOE) — 用于数据库应用程序服务器和逻辑服务器,此操 作环境包含HP-UX 11i v1 Foundation OE 软件包,以及其他用于支持企业级服务器的应用程序,如 GlancePlus Pak。这种操作环境与 HP-UX 11i 捆绑在一起时称为HPUX11i-OE-Ent。 c)HP-UX 11i v1 Mission Critical OE (MCOE) — 用于功能强大的大型后端应用程序服务 器和数据库服务器,这些服务器可访问客户文件并进行事务处理,此操作环境包含Enterprise OE 软件包,以及其他用于支持关键任务服务器的应用程序,如 HP Serviceguard 和 Workload Manager。这种操作环境与 HP-UX 11i 捆绑在一起称为HPUX11i-OE-MC。 d)HP-UX 11i v1 Minimal Technical OE (MTOE) — 用于运行HP-UX 11i v1 的工作站,此 操作环境包括 Mozilla 应用程序套件、Perl、VxVM 和 Judy 应用程序,以及 OpenGL Graphics Developer's Kit。这种操作环境与 HP-UX 11i 捆绑在一起时称为HPUX11i-MTOE。 e)HP-UX 11i v1 Technical Computing OE (TCOE) — 用于进行大量计算的工作站和服务器 应用程序,此操作环境包含 MTOE 软件包以及大量图形应用程序和 Math Library。这种操作环境与 HP-UX 11i 捆绑在一起时称为 HPUX11i- TCOE。 不同的HP-UX操作环境有不同的内核参数,当HP-UX启动时,HP-UX内核被调入到内存时,HP-UX的内存被分为两个单元:内核区域和用户区域,内核区域存放并运行着核心代码,顾名思义,用户区域也存放并运行用户程序。作为用户进程来讲它是不能访问内核区域内存空间以及其他用户进程的地址空间的,核心代码也同样不能访问用户区地地址空间,HP-UX可以利用一些特殊的核心函数即系统调用来间接完成这些访问。HP-UX内核参数就是通过内核(vmunix)的调入来实现其设置。 内核参数的可调整性正是UNIX灵活性的反映,同时也加大了UNIX管理的复杂性。可调整的HP-UX内核参数容许系统管理员依据特定的系统需要,或者为了更好的性能,或者更有效的资源分配对HP-UX内核参数进行设置。每一个HP-UX内核参数的理想值同特定的系统硬件配置和不同的应用相关。惠普对每一个HP-UX内核参数提供了一个缺省值,但依据生产的实际情况对HP-UX内核参数进行调整是必须。不同的HP-UX内核参数通常属于不同的子系统,有些是独立的,有些是相互关联的。需要说明的是,每一个HP-UX内核参数依据操作系统版本的不同,特定HP-UX内核参数的行为模式可能完全不一样,本书主要就HP-UX release 11i版进行说明。其他版本请参考相应版本的releases of HP-UX。

Kernel内存管理slub算法原理

内核管理页面使用了2个算法:伙伴算法和slub算法,伙伴算法以页为单位管理内存,但在大多数情况下,程序需要的并不是一整页,而是几个、几十个字节的小内存。于是需要另外一套系统来完成对小内存的管理,这就是slub系统。slub系统运行在伙伴系统之上,为内核提供小内存管理的功能。 slub把内存分组管理,每个组分别包含2^3、2^4、...2^11个字节,在4K页大小的默认情况下,另外还有两个特殊的组,分别是96B和192B,共11组。之所以这样分配是因为如果申请2^12B大小的内存,就可以使用伙伴系统提供的接口直接申请一个完整的页面即可。 slub就相当于零售商,它向伙伴系统“批发”内存,然后在零售出去。一下是整个slub系统的框图: 一切的一切源于kmalloc_caches[12]这个数组,该数组的定义如下: structkmem_cachekmalloc_caches[PAGE_SHIFT] __cacheline_aligned; 每个数组元素对应一种大小的内存,可以把一个kmem_cache结构体看做是一个特定大小内存的零售商,整个slub系统中共有12个这样的零售商,每个“零

售商”只“零售”特定大小的内存,例如:有的“零售商”只"零售"8Byte大小的内存, 有的只”零售“16Byte大小的内存。 每个零售商(kmem_cache)有两个“部门”,一个是“仓库”:kmem_cache_node,一个“营业厅”:kmem_cache_cpu。“营业厅”里只保留一个slab,只有在营业厅(kmem_cache_cpu)中没有空闲内存的情况下才会从仓库中换出其他的slab。 所谓slab就是零售商(kmem_cache)批发的连续的整页内存,零售商把这些整页的内存分成许多小内存,然后分别“零售”出去,一个slab可能包含多个连续的内存页。slab的大小和零售商有关。 相关数据结构: 物理页按照对象(object)大小组织成单向链表,对象大小时候objsize指定的。例如16字节的对象大小,每个object就是16字节,每个object包含指向下一个object的指针,该指针的位置是每个object的起始地址+offset。每个object示意 图如下: void*指向的是下一个空闲的object的首地址,这样object就连成了一个单链表。 向slub系统申请内存块(object)时:slub系统把内存块当成object看待 1. slub系统刚刚创建出来,这是第一次申请。 此时slub系统刚建立起来,营业厅(kmem_cache_cpu)和仓库 (kmem_cache_node)中没有任何可用的slab可以使用,如下图中1所示:

相关文档
最新文档