自己刚刚组装的电脑玩游戏自动关机一卡一卡的是不是我的CPU不行了要换一个在这里我请求各位帮忙,帮我看一下是

我的电脑是5-6年前的组装电脑之前放置了一段时间现在玩游戏的时候反应有点慢或玩不到我想加速是要换主板吗_百度知道
我的电脑是5-6年前的组装电脑之前放置了一段时间现在玩游戏的时候反应有点慢或玩不到我想加速是要换主板吗
我有更好的答案
这是必须的,显卡和内存都要加大
显卡,内存,主板3样都要换新的吗?知道大概需要多少钱吗?
主板上包括显卡。好一点的400-500吧。内存2G的好像是160元,1G80元
采纳率:6%
电脑能打开的话硬件应该就没问题。你那是只是在玩游戏的时候卡还是开机之后一直都卡。如果只是玩游戏的时候卡,那还得看你玩的什么游戏了,你都5-6年前的电脑了,配置肯定不会特别好,现在的游戏,都比较烧显卡,自然带起来就吃力。如果你是说你斗地主卡,那我没什么说的了- -如果开机之后一直卡,那建议你找专业修电脑的给你看看吧我估计7-8成是硬件该更新了。
建议先清理电脑系统垃圾文件以及机箱内的灰尘,显卡和内存视情况而定。注意内存现在的三代不一定能在你电脑上用。
这个问题,差不多都的换了,主板,CPU,玩游戏显卡跟不上也不行,显卡也的跟上,至于硬盘,读写速度跟不上,也的换,这样一样,你就不如换一台电脑。 单个换的话,本人不介意,因为你这样一来,也没达到效果,还花不少的银子,现在重配一台也用不了多少钱,介意你要是想换的话,你就还是考虑的全换吧,比分开换划算。
其他1条回答
为您推荐:
其他类似问题
组装电脑的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。我电脑用过一个小时后就会迟钝 测试下看时 CPU时00%是为什么是不是要换一个CPU
按时间排序
经常出现CPU占用100%的情况,主要问题可能发生在下面的某些方面: CPU占用率高的九种可能 1、防杀毒软件造成故障 由于新版的KV、金山、瑞星都加入了对网页、插件、邮件的随机监控,无疑增大了系统负担。处理方式:基本上没有合理的处理方式,尽量使用最少的监控服务吧,者,升级你的硬件配备。 2、驱动没有经过认证,造成CPU资源占用100% 大量的测试版的驱动在网上泛滥,造成了难以发现的故障原因。 处理方式:尤其是显卡驱动特别要注意,建议使用微软认证的或由官方发布的驱动,并且严格核对型号、版本。 3、病毒、木马造成 大量的蠕虫病毒在系统内部迅速复制,造成CPU占用资源率据高不下。解决办法:用可靠的杀毒软件彻底清理系统内存和本地硬盘,并且打开系统设置软件,察看有无异常启动的程序。经常性更新升级杀毒软件和防火墙,加强防毒意识,掌握正确的防杀毒知识。 4、控制面板—管理工具—服务—RISING REALTIME MONITOR SERVICE点鼠标右键,改为手动。 5、开始-&;运行-&;msconfig-&;启动,关闭不必要的启动项,重启。 6、查看“svchost”进程。 svchost.exe是Windows XP系统的一个核心进程。svchost.exe不单单只出现在Windows XP中,在使用NT内核的Windows系统中都会有svchost.exe的存在。一般在Windows 2000中svchost.exe进程的数目为2个,而在Windows XP中svchost.exe进程的数目就上升到了4个及4个以上。 7、查看网络连接。主要是网卡。 8、查看网络连接 当安装了Windows XP的计算机做服务器的时候,收到端口 445 上的连接请求时,它将分配内存和少量地调配 CPU资源来为这些连接提供服务。当负荷过重的时候,CPU占用率可能过高,这是因为在工作项的数目和响应能力之间存在固有的权衡关系。你要确定合适的 MaxWorkItems 设置以提高系统响应能力。如果设置的值不正确,服务器的响应能力可能会受到影响,或者某个用户独占太多系统资源。 要解决此问题,我们可以通过修改注册表来解决:在注册表编辑器中依次展开[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServiceslanmanserver ]分支,在右侧窗口中新建一个名为“maxworkitems”的DWORD值。然后双击该值,在打开的窗口中键入下列数值并保存退出: 9、看看是不是Windows XP使用鼠标右键引起CPU占用100% 在资源管理器里面,当你右键点击一个目录或一个文件,你将有可能出现下面所列问题: 任何文件的拷贝操作在那个时间将有可能停止相应 网络连接速度将显著性的降低 所有的流输入/输出操作例如使用Windows Media Player听音乐将有可能是音乐失真成因: 当你在资源管理器里面右键点击一个文件或目录的时候,当快捷菜单显示的时候,CPU占用率将增加到100%,当你关闭快捷菜单的时候才返回正常水平。 解决方法: 方法一:关闭“为菜单和工具提示使用过渡效果” 1、点击“开始”--“控制面板” 2、在“控制面板”里面双击“显示” 3、在“显示”属性里面点击“外观”标签页 4、在“外观”标签页里面点击“效果” 5、在“效果”对话框里面,清除“为菜单和工具提示使用过渡效果”前面的复选框接着点击两次“确定”按钮。 方法二:在使用鼠标右键点击文件或目录的时候先使用鼠标左键选择你的目标文件或目录。然后再使用鼠标右键弹出快捷菜单。 一般情况下CPU占了100%的话我们的电脑总会慢下来,而很多时候我们是可以通过做一点点的改动就可以解决,而不必问那些大虾了。 当机器慢下来的时候,首先我们想到的当然是任务管理器了,看看到底是哪个程序占了较搞的比例,如果是某个大程序那还可以原谅,在关闭该程序后只要CPU正常了那就没问题;如果不是,那你就要看看是什幺程序了,当你查不出这个进程是什幺的时候就去google或者baidu搜。有时只结束是没用的,在xp下我们可以结合msconfig里的启动项,把一些不用的项给关掉。在2000下可以去下个winpatrol来用。 一些常用的软件,比如浏览器占用了很搞的CPU,那幺就要升级该软件或者干脆用别的同类软件代替,有时软件和系统会有点不兼容,当然我们可以试下xp系统下给我们的那个兼容项,右键点该.exe文件选兼容性。 svchost.exe有时是比较头痛的,当你看到你的某个svchost.exe占用很大CPU时你可以去下个aports或者fport来检查其对应的程序路径,也就是什幺东西在掉用这个svchost.exe,如果不是c:Windowssystem32(xp)或c:winntsystem32(2000)下的,那就可疑。升级杀毒软件杀毒吧。 右击文件导致100%的CPU占用我们也会遇到,有时点右键停顿可能就是这个问题了。官方的解释:先点左键选中,再右键(不是很理解)。非官方:通过在桌面点右键-属性-外观-效果,取消”为菜单和工具提示使用下列过度效果(U)“来解决。还有某些杀毒软件对文件的监控也会有所影响,可以关闭杀毒软件的文件监控;还有就是对网页,插件,邮件的监控也是同样的道理。 一些驱动程序有时也可能出现这样的现象,最好是选择微软认证的或者是官方发布的驱动来装,有时可以适当的升级驱动,不过记得最新的不是最好的。 CPU降温软件,由于软件在运行时会利用所以的CPU空闲时间来进行降温,但Windows不能分辨普通的CPU占用和降温软件的降温指令之间的区别,因此CPU始终显示100%,这个就不必担心了,不影响正常的系统运行。 在处理较大的word文件时由于word的拼写和语法检查会使得CPU累,只要打开word的工具-选项-拼写和语法把”检查拼写和检查语法“勾去掉。 单击avi视频文件后CPU占用率高是因为系统要先扫描该文件,并检查文件所有部分,并建立索引;解决办法:右击保存视频文件的文件夹-属性-常规-高级,去掉为了快速搜索,允许索引服务编制该文件夹的索引的勾。 CPU占用100%案例分析 1、dllhost进程造成CPU使用率占用100% 特征:服务器正常CPU消耗应该在75%以下,而且CPU消耗应该是上下起伏的,出现这种问题的服务器,CPU会突然一直处100%的水平,而且不会下降。查看任务管理器,可以发现是DLLHOST.EXE消耗了所有的CPU空闲时间,管理员在这种情况下,只好重新启动IIS服务,奇怪的是,重新启动IIS服务后一切正常,但可能过了一段时间后,问题又再次出现了。 直接原因: 有一个或多个ACCESS数据库在多次读写过程中损坏,微软的MDAC系统在写入这个损坏的ACCESS文件时,ASP线程处于BLOCK状态,结果其它线程只能等待,IIS被死锁了,全部的CPU时间都消耗在DLLHOST中。 解决办法: 安装“一流信息监控拦截低场保�褂闷渲械摹笆紫�募�觳楣买IS健康检查官”软件, 启用”查封我号锁模块”,设置: --wblock=yes 监控的目录,请指定您的主机的文件所在目录: --wblockdir=d: est 监控生成的日志的文件保存位置在安装目录的log目录中,文件名为:logblock.htm 停止IIS,再启动“首席文件检查官IIS健康检查官”,再启动IIS,“首席文件检查官IIS健康检查官”会在logblock.htm中记录下最后写入的ACCESS文件的。 过了一段时间后,当问题出来时,例如CPU会再次一直处100%的水平,可以停止IIS,检查logblock.htm所记录的最后的十个文件,注意,最有问题的往往是计数器类的ACCESS文件,例如:”**COUNT.MDB”,”**COUNT.ASP”,可以先把最后十个文件或有所怀疑的文件删除到回收站中,再启动IIS,看看问题是否再次出现。我们相信,经过仔细的查找后,您肯定可以找到这个让您操心了一段时间的文件的。 找到这个文件后,可以删除它,或下载下来,用ACCESS2000修复它,问题就解决了。 2、svchost.exe造成CPU使用率占用100% 在win.ini文件中,在[Windows]下面,“run=”和“load=”是可能加载“木马”程序的途径,必须仔细留心它们。一般情况下,它们的等号后面什幺都没有,如果发现后面跟有路径与文件名不是你熟悉的启动文件,你的计算机就可能中上“木马”了。当然你也得看清楚,因为好多“木马”,如“AOL Trojan木马”,它把自身伪装成command.exe文件,如果不注意可能不会发现它不是真正的系统启动文件。 在system.ini文件中,在[BOOT]下面有个“shell=文件名”。正确的文件名应该是“explorer.exe”,如果不是“explorer.exe”,而是“shell= explorer.exe 程序名”,那幺后面跟着的那个程序就是“木马”程序,就是说你已经中“木马”了。 在注册表中的情况最复杂,通过regedit命令打开注册表编辑器,在点击至:“HKEY-LOCAL-MACHINESoftwareMicrosoftWindowsCurrentVersionRun”目录下,查看键值中有没有自己不熟悉的自动启动文件,扩展名为EXE,这里切记:有的“木马”程序生成的文件很像系统自身文件,想通过伪装蒙混过关,如“Acid Battery v1.0木马”,它将注册表“HKEY-LOCAL-MACHINESOFTWAREMicrosoftWindowsCurrentVersionRun”下的Explorer 键值改为Explorer=“C:Windowsexpiorer.exe”,“木马”程序与真正的Explorer之间只有“i”与“l”的差别。当然在注册表中还有很多地方都可以隐藏“木马”程序,如:“HKEY-CURRENT-USERSoftwareMicrosoftWindowsCurrentVersionRun”、“HKEY-USERS****SoftwareMicrosoftWindowsCurrentVersionRun”的目录下都有可能,最好的办法就是在“HKEY-LOCAL-MACHINESoftwareMicrosoftWindowsCurrentVersionRun”下找到“木马该病毒也称为“Code Red II(红色代码2)”病毒,与早先在西方英文系统下流行“红色代码”病毒有点相反,在国际上被称为VirtualRoot(虚拟目录)病毒。该蠕虫病毒利用Microsoft已知的溢出漏洞,通过80端口来传播到其它的Web页服务器上。受感染的机器可由黑客们通过Http Get的请求运行scripts/root.exe来获得对受感染机器的完全控制权。 当感染一台服务器成功了以后,如果受感染的机器是中文的系统后,该程序会休眠2天,别的机器休眠1天。当休眠的时间到了以后,该蠕虫程序会使得机器重新启动。该蠕虫也会检查机器的月份是否是10月或者年份是否是2002年,如果是,受感染的服务器也会重新启动。当Windows NT系统启动时,NT系统会自动搜索C盘根目录下的文件explorer.exe,受该网络蠕虫程序感染的服务器上的文件explorer.exe也就是该网络蠕虫程序本身。该文件的大小是8192字节,VirtualRoot网络蠕虫程序就是通过该程序来执行的。同时,VirtualRoot网络蠕虫程序还将cmd.exe的文件从Windows NT的system目录拷贝到别的目录,给黑客的入侵敞开了大门。它还会修改系统的注册表项目,通过该注册表项目的修改,该蠕虫程序可以建立虚拟的目录C或者D,病毒名由此而来。值得一提的是,该网络蠕虫程序除了文件explorer.exe外,其余的操作不是基于文件的,而是直接在内存中来进行感染、传播的,这就给捕捉带来了较大难度。 ”程序的文件名,再在整个注册表中搜索即可。 我们先看看微软是怎样描述svchost.exe的。在微软知识库314056中对svchost.exe有如下描述:svchost.exe 是从动态链接库 (DLL) 中运行的服务的通用主机进程名称。 其实svchost.exe是Windows XP系统的一个核心进程。svchost.exe不单单只出现在Windows XP中,在使用NT内核的Windows系统中都会有svchost.exe的存在。一般在Windows 2000中svchost.exe进程的数目为2个,而在Windows XP中svchost.exe进程的数目就上升到了4个及4个以上。所以看到系统的进程列表中有几个svchost.exe不用那幺担心。 svchost.exe到底是做什幺用的呢? 首先我们要了解一点那就是Windows系统的中的进程分为:独立进程和共享进程这两种。由于Windows系统中的服务越来越多,为了节约有限的系统资源微软把很多的系统服务做成了共享模式。那svchost.exe在这中间是担任怎样一个角色呢? svchost.exe的工作就是作为这些服务的宿主,即由svchost.exe来启动这些服务。svchost.exe只是负责为这些服务提供启动的条件,其自身并不能实现任何服务的功能,也不能为用户提供任何服务。svchost.exe通过为这些系统服务调用动态链接库(DLL)的方式来启动系统服务。 svchost.exe是病毒这种说法是任何产生的呢? 因为svchost.exe可以作为服务的宿主来启动服务,所以病毒、木马的编写者也挖空心思的要利用svchost.exe的这个特性来迷惑用户达到入侵、破坏计算机的目的。 如何才能辨别哪些是正常的svchost.exe进程,而哪些是病毒进程呢? svchost.exe的键值是在“HKEY_LOCAL_MACHINESoftwareMicrosoftWindows NTCurrentVersionSvchost”,如图1所示。图1中每个键值表示一个独立的svchost.exe组。 微软还为我们提供了一种察看系统正在运行在svchost.exe列表中的服务的方法。以Windows XP为例:在“运行”中输入:cmd,然后在命令行模式中输入:tasklist /svc。系统列出如图2所示的服务列表。图2中红框包围起来的区域就是svchost.exe启动的服务列表。如果使用的是Windows 2000系统则把前面的“tasklist /svc”命令替换为:“tlist -s”即可。如果你怀疑计算机有可能被病毒感染,svchost.exe的服务出现异常的话通过搜索svchost.exe文件就可以发现异常情况。一般只会找到一个在:“C:WindowsSystem32”目录下的svchost.exe程序。如果你在其它目录下发现svchost.exe程序的话,那很可能就是中毒了。 还有一种确认svchost.exe是否中毒的方法是在任务管理器中察看进程的执行路径。但是由于在Windows系统自带的任务管理器不能察看进程路径,所以要使用第三方的进程察看工具。 上面简单的介绍了svchost.exe进程的相关情况。总而言之,svchost.exe是一个系统的核心进程,并不是病毒进程。但由于svchost.exe进程的特殊性,所以病毒也会千方百计的入侵svchost.exe。通过察看svchost.exe进程的执行路径可以确认是否中毒。 3、Services.exe造成CPU使用率占用100% 症状 在基于 Windows 2000 的计算机上,Services.exe 中的 CPU 使用率可能间歇性地达到100 %,并且计算机可能停止响应(挂起)。出现此问题时,连接到该计算机(如果它是文件服务器或域控制器)的用户会被断开连接。您可能还需要重新启动计算机。如果 Esent.dll 错误地处理将文件刷新到磁盘的方式,则会出现此症状。 解决方案 Service Pack 信息 要解决此问题,请获取最新的 Microsoft Windows 2000 Service Pack。有关其它信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章: 260910 如何获取最新的 Windows 2000 Service Pack 修复程序信息 Microsoft 提供了受支持的修补程序,但该程序只是为了解决本文所介绍的问题。只有计算机遇到本文提到的特定问题时才可应用此修补程序。此修补程序可能还会接受其它一些测试。因此,如果这个问题没有对您造成严重的影响,Microsoft 建议您等待包含此修补程序的下一个 Windows 2000 Service Pack。 要立即解决此问题,请与“Microsoft 产品支持服务”联系,以获取此修补程序。有关“Microsoft 产品支持服务”电话号码和支持费用信息的完整列表,请访问 Microsoft Web 站点: 注意 :特殊情况下,如果 Microsoft 支持专业人员确定某个特定的更新程序能够解决您的问题,可免收通常情况下收取的电话支持服务费用。对于特定更新程序无法解决的其它支持问题和事项,将正常收取支持费用。 4、正常软件造成CPU使用率占用100% 首先,如果是从开机后就发生上述情况直到关机。那幺就有可能是由某个随系统同时登陆的软件造成的。可以通过运行输入“msconfig”打开“系统实用配置工具”,进入“启动”选项卡。接着,依次取消可疑选项前面的对钩,然后重新启动电脑。反复测试直到找到造成故障的软件。或者可以通过一些优化软件如“优化大师”达到上述目的。另:如果键盘内按键卡住也可能造成开机就出现上述问题。 如果是使用电脑途中出项这类问题,可以调出任务管理器(WINXP CTRL+ALT+DEL WIN2000 CTRL+SHIFT“ESC),进入”进程“选项卡,看”CPU“栏,从里面找到占用资源较高的程序(其中SYSTEM IDLE PROCESS是属于正常,它的值一般都芨撸��淖饔檬歉嫠叩鼻澳憧捎玫腃PU资源是多少,所以它的值越高越好)通过搜索功能找到这个进程属于哪个软件。然后,可以通过升级、关闭、卸载这个软件或者干脆找个同类软件替换,问题即可得到解决。 5、病毒、木马、间谍软件造成CPU使用率占用100% 出现CPU占用率100% 的故障经常是因为病毒木马造成的,比如震荡波病毒。应该首先更新病毒库,对电脑进行全机扫描 。接着,在使用反间谍软件Ad—Aware,检查是否存在间谍软件。论坛上有不少朋友都遇到过svchost.exe占用CPU100%,这个往往是中毒的表现。 svchost.exe Windows中的系统服务是以动态链接库(DLL)的形式实现的,其中一些会把可执行程序指向svchost.exe,由它调用相应服务的动态链接库并加上相应参数来启动服务。正是因为它的特殊性和重要性,使它更容易成为了一些病毒木马的宿主。 6、explorer.exe进程造成CPU使用率占用100% 在system.ini文件中,在[BOOT]下面有个“shell=文件名”。正确的文件名应该是“explorer.exe”,如果不是“explorer.exe”,而是“shell= explorer.exe 程序名”,那幺后面跟着的那个程序就是“木马”程序,就是说你已经中“木马”了。 在注册表中的情况最复杂,通过regedit命令打开注册表编辑器,在点击至:“HKEY-LOCAL-MACHINESoftwareMicrosoftWindowsCurrentVersionRun”目录下,查看键值中有没有自己不熟悉的自动启动文件,扩展名为EXE,这里切记:有的“木马”程序生成的文件很像系统自身文件,想通过伪装蒙混过关,如“Acid Battery v1.0木马”,它将注册表“HKEY-LOCAL-MACHINESOFTWAREMicrosoftWindowsCurrentVersionRun”下的 Explorer 键值改为Explorer=“C:Windowsexpiorer.exe”,“木马”程序与真正的Explorer之间只有“i”与“l”的差别。当然在注册表中还有很多地方都可以隐藏“木马”程序,如:“HKEY-CURRENTUSERSoftwareMicrosoftWindowsCurrentVersionRun”、“HKEYUSERS****SoftwareMicrosoftWindowsCurrentVersionRun”的目录下都有可能,最好的办法就是在“HKEYLOCALMACHINESoftwareMicrosoftWindowsCurrentVersionRun”下找到“木马”程序的文件名,再在整个注册表中搜索即可。 7、超线程导致CPU使用率占用100% 这类故障的共同原因就是都使用了具有超线程功能的P4 CPU。我查找了一些资料都没有明确的原因解释。据一些网友总结超线程似乎和天网防火墙有冲突,可以通过卸载天网并安装其它防火墙解决,也可以通过在BIOS中关闭超线程功能解决。 8、AVI视频文件造成CPU使用率占用100% 在Windows XP中,单击一个较大的AVI视频文件后,可能会出现系统假死现象,并且造成exploere.exe进程的使用率100%,这是因为系统要先扫描该文件,并检查文件所有部分,建立索引。如果文件较大就会需要较长时间并造成CPU占用率100%。解决方法:右键单击保存视频文件的文件夹,选择”属性—&常规—&高级“,去掉”为了快速搜索,允许索引服务编制该文件夹的索引“前面复选框的对钩即可。 9、杀毒软件CPU使用率占用100% 现在的杀毒软件一般都加入了,对网页、邮件、个人隐私的即时监空功能,这样无疑会加大系统的负担。比如:在玩游戏的时候,会非常缓慢。关闭该杀毒软件是解决得最直接办法。 10、处理较大的Word文件时CPU使用率过高 上述问题一般还会造成电脑假死,这些都是因为WORD的拼写和语法检查造成的,只要打开WORD的“工具—选项”,进入“拼写和语法”选项卡,将其中的“键入时检查拼写”和“键入时检查语法”两项前面的复选框中的钩去掉即可。 11、网络连接导致CPU使用率占用100% 当你的Windows2000/xp作为服务器时,收到来自端口445上的连接请求后,系统将分配内存和少量CPU资源来为这些连接提供服务,当负荷过重,就会出现上述情况。要解决这个问题可以通过修改注册表来解决,打开注册表,找到HKEY—LOCAL—MACHNESYSTEMCurrentControlSetServiceslanmanserver,在右面新建一个名为&;maxworkitems&;的DWORD值.然后双击该值,如果你的电脑有512以上内存,就设置为&;1024&;,如果小于512,就设置为256. 一些不完善的驱动程序也可以造成CPU使用率过高 经常使用待机功能,也会造成系统自动关闭硬盘DMA模式。这不仅会使系统性能大幅度下降,系统启动速度变慢,也会使是系统在运行一些大型软件和游戏时CPU使用率100%,产生停顿。 进程占用CPU 100%时可能中的病毒 system Idle Process 进程文件: [system process] or [system process] 进程名称: Windows内存处理系统进程 描 述: Windows页面内存管理进程,拥有0级优先。 介 绍:该进程作为单线程运行在每个处理器上,并在系统不处理其它线程的时候分派处理器的时间。它的CPU占用率越大表示可供分配的CPU资源越多,数字越小则表示CPU资源紧张。 Spoolsv.exe 进程文件: spoolsv or Spoolsv.exe 进程名称: Printer Spooler Service 描 述: Windows打印任务控制程序,用以打印机就绪。 介 绍:缓冲(spooler)服务是管理缓冲池中的打印和传真作业。 Spoolsv.exe→打印任务控制程序,一般会先加载以供列表机打印前的准备?
可能是不常用的软件自动开启过多,系统过慢导致的楼主可以使用腾讯电脑管家的电脑加速功能打开腾讯电脑管家--电脑加速--一键加速
电脑散热不好,建议清洗风扇或更换一个好点的风扇
系统有没中毒
测试软件未推出
迟钝? 那就是内存的问题啊啊
传输数据的时候导致的啊
更换一下内存啊 !!
感谢您为社区的和谐贡献力量请选择举报类型
经过核实后将会做出处理感谢您为社区和谐做出贡献
确定要取消此次报名,退出该活动?
请输入私信内容:百度知道 - 信息提示
知道宝贝找不到问题了&_&!!
该问题可能已经失效。
秒以后自动返回下面是网上看到的一些关于内存和CPU方面的一些很不错的文章. 整理如下:
转: CPU的等待有多久?
原文标题:
原文地址:
注:本人水平有限,只好挑一些国外高手的精彩文章翻译一下。一来自己复习,二来与大家分享。
&& 本文以一个现代的、实际的个人电脑为对象,分析其中()以及各类子系统的运行速度——延迟和数据吞吐量。通过粗略的估算各个组件的相对运行速度,希望能给大家留下一个比较直观的印象。本文中的数据来自实际应用,而非理论最大值。时间的单位是纳秒(,十亿分之一秒),毫秒(,千分之一秒),和秒()。吞吐量的单位是兆字节()和千兆字节()。让我们先从和内存开始,下图是北桥部分: &&
&& 第一个令人惊叹的事实是:快得离谱。在上,大部分简单指令的执行只需要一个时钟周期,也就是纳秒。即使是真空中传播的光,在这段时间内也只能走厘米(约英寸)。把上述事实记在心中是有好处的。当你要对程序做优化的时候就会想到,执行指令的开销对于当今的而言是多么的微不足道。 &&
当运转起来以后,它便会通过和对系统中的主存进行读写访问。使用的是静态存储器)。相对于系统主存中使用的动态存储器(),读写速度快得多、造价也高昂得多。一般被放置在芯片的内部,加之使用昂贵高速的存储器,使其给带来的延迟非常低。在指令层次上的优化(),其效果是与优化后代码的大小息息相关。由于使用了高速缓存技术(),那些能够整体放入中的代码,和那些在运行时需要不断调入调出()的代码,在性能上会产生非常明显的差异。
&& 正常情况下,当操作一块内存区域时,其中的信息要么已经保存在,要么就需要将之从系统主存中调入,然后再处理。如果是后一种情况,我们就碰到了第一个瓶颈,一个大约个时钟周期的延迟。在此期间如果没有其他事情要做,则往往是处在停机状态的()。为了给大家一个直观的印象,我们把的一个时钟周期看作一秒。那么,从读取信息就好像是拿起桌上的一张草稿纸(秒);从读取信息则是从身边的书架上取出一本书(秒);而从主存中读取信息则相当于走到办公楼下去买个零食(分钟)。
&& 主存操作的准确延迟是不固定的,与具体的应用以及其他许多因素有关。比如,它依赖于列选通延迟以及内存条的型号,它还依赖于指令预取的成功率。指令预取可以根据当前执行的代码来猜测主存中哪些部分即将被使用,从而提前将这些信息载入。
&& 看看的性能,再对比主存,就会发现:配置更大的或者编写能更好的利用的应用程序,会使系统的性能得到多么显著的提高。如果想进一步了解有关内存的诸多信息,读者可以参阅所写的一篇经典文章《》。
&& 人们通常把与内存之间的瓶颈叫做()。当今系统的前端总线带宽约为,看起来很令人满意。在这个速度下,你可以在秒内从内存中读取的信息,或者纳秒内读取字节。遗憾的是,这个吞吐量只是理论最大值(图中其他数据为实际值),而且是根本不可能达到的,因为主存控制电路会引入延迟。在做内存访问时,会遇到很多零散的等待周期。比如电平协议要求,在选通一行、选通一列、取到可靠的数据之前,需要有一定的信号稳定时间。由于主存中使用电容来存储信息,为了防止因自然放电而导致的信息丢失,就需要周期性的刷新它所存储的内容,这也带来额外的等待时间。某些连续的内存访问方式可能会比较高效,但仍然具有延时。而那些随机的内存访问则消耗更多时间。所以延迟是不可避免的。
图中下方的南桥连接了很多其他总线(如:)和外围设备:
令人沮丧的是,南桥管理了一些反应相当迟钝的设备,比如硬盘。就算是缓慢的系统主存,和硬盘相比也可谓速度如飞了。继续拿办公室做比喻,等待硬盘寻道的时间相当于离开办公大楼并开始长达一年零三个月的环球旅行。这就解释了为何电脑的大部分工作都受制于磁盘,以及为何数据库的性能在内存缓冲区被耗尽后会陡然下降。同时也解释了为何充足的(用于缓冲)和高速的磁盘驱动器对系统的整体性能如此重要。
虽然磁盘的"连续"存取速度确实可以在实际使用中达到,但这并非故事的全部。真正令人头疼的瓶颈在于寻道操作,也就是在磁盘表面移动读写磁头到正确的磁道上,然后再等待磁盘旋转到正确的位置上,以便读取指定扇区内的信息。(每分钟绕转次数)用来指示磁盘的旋转速度:越大,耽误在寻道上的时间就越少,所以越高的意味着越快的磁盘。这里有一篇由两个的研究生写的很酷的文章,其中讲述了寻道时间对系统性能的影响:《》
&& 当磁盘驱动器读取一个大的、连续存储的文件时会达到更高的持续读取速度,因为省去了寻道的时间。文件系统的碎片整理器就是用来把文件信息重组在连续的数据块中,通过尽可能减少寻道来提高数据吞吐量。然而,说到计算机实际使用时的感受,磁盘的连续存取速度就不那么重要了,反而应该关注驱动器在单位时间内可以完成的寻道和随机操作的次数。对此,固态硬盘可以成为一个很棒的选择。
&& 硬盘的也有助于改进性能。虽然的只能覆盖整个磁盘容量的,可别看只有这么一点大,其效果十分明显。它可以把一组零散的写入操作合成一个,也就是。同样的,为了提高效率,一系列读取操作也可以被重组,而且操作系统和驱动器固件都会参与到这类优化中来。
最后,图中还列出了网络和其他总线的实际数据吞吐量。火线仅供参考,芯片组并不直接支持火线。我们可以把看作是计算机之间的总线。去访问那些速度很快的网站(比如),延迟大约毫秒,与硬盘驱动器带来的延迟相当。事实上,尽管硬盘比内存慢了个数量级,它的速度与是在同一数量级上的。目前,一般家用网络的带宽还是要落后于硬盘连续读取速度的,但"网络就是计算机"这句话可谓名符其实。如果将来比硬盘还快了,那会是个什么景象呢?
我希望这些图片能对您有所帮助。当这些数字一起呈现在我面前时,真的很迷人,也让我看到了计算机技术发展到了哪一步。前文分开的两个图片只是为了叙述方便,我把包含南北桥的整张图片也贴出来,供您参考。
转: CPU如何操作内存
原文标题:
原文地址:
&& 注:本人水平有限,只好挑一些国外高手的精彩文章翻译一下。一来自己复习,二来与大家分享。
&& 在你试图理解一个复杂的系统时,如果能揭去表面的抽象并专注于最低级别的概念,往往会有不小的收获。在这个精神的指导下,让我们看看对于内存和端口操作来说最简单、最基础的概念,即与总线之间的接口。其中的细节是很多上层概念的基础,比如线程同步。当然了,既然我是个程序员,就暂且忽略那些只有电子工程师才会去关注的东西吧。下图是我们的老朋友,:
&& 处理器有个管脚,其中约半数仅仅用于供电而不参与数据传输。当你把这些管脚按照功能分类后,就会发现这个处理器的物理接口惊人的简单。本图展示了参与内存和端口操作的重要管脚:地址线,数据线,请求线。这些操作均发生在前端总线的事务上下文结构中。前端总线事务的执行包含五个阶段:仲裁,请求,侦听,响应,数据操作。在执行事务的过程中,前端总线上的各个部件扮演着不同的角色。这些部件称之为。通常,就是全部的处理器外加北桥。
本文只分析请求阶段。在此阶段中,发出请求的往往是一个处理器,它输出两个数据包。下图列出了第一个数据包中最为重要的位,这些数据位通过处理器的地址线和请求线输出:
&& 地址线输出指定了事务发生的物理内存起始地址。我们有条地址线,他们指定了数据包的第至第位,第至第位为。因此,实际上这条地址线构成了一个位的、以字节对齐的地址,正好覆盖的物理内存。这种设定从奔腾就开始了。请求线指定了事务的类型。当事务类型为请求时,地址线指出的是端口地址而不是内存地址。当第一个数据包被发送以后,同样由这组管脚,在下一个总线时钟周期发送第二个数据包:
&& 属性信号()很有趣,它反映了处理器所支持的种内存缓冲功能。把这些信息发布到前端总线后,发出请求的就可以让其他处理器知道如何根据当前事务处理他们自己的,以及让内存控制器(也就是北桥)知道该如何应对。一块指定内存区域的缓存类型由处理器通过查询页表()来决定,页表由内核维护。
&& 典型的情况是,内核把全部内存都视为"回写"类型(),从而获得最好的性能。在回写模式下,内存的最小访问单元为一个(),在中是字节。当程序想读取内存中的一个字节时,处理器会从读取包含此字节的整条缓存线的内容。当程序做写入内存操作时,处理器只是修改中的对应缓存线,而不会更新主存中的信息。之后,当真的需要更新主存时,处理器会把那个被修改了的缓存线整体放到总线上,一次性写入内存。所以大部分的请求事务,其数据长度字段都是(),对应字节。下图展示了当中没有对应数据时,内存读取访问的过程:
在计算机上,有些物理内存范围被而不是实际的存储器地址,比如硬盘和网卡。这使得驱动程序可以像读写内存那样,方便的与设备通信。内核会在页表中标记出这类内存映射区域为不可缓存的()。对不可缓存的内存区域的访问操作会被总线原封不动的按顺序执行,其操作与应用程序或驱动程序所发出的请求完全一致。因此,这时程序可以精确控制读写单个字节、字、或其它长度的信息。这都是通过设置第二个数据包中的字节使能掩码()来完成的。
前面讨论的这些基本知识还包含很多关联的内容。比如:
、如果应用程序想要尽可能高的运行速度,就应该把会被一起访问的数据尽量组织在同一条缓存线中。一旦这条缓存线被载入,之后的读取操作就会,不再需要额外的内存访问了。
、对于回写式内存访问,作用于一条缓存线的任何内存操作都一定是原子的()。这种能力是由处理器的提供的,所有数据被同时读写,中途不会被其他处理器或线程打断。特别的,位和位的内存操作,只要不跨越缓存线的边界,就都是原子操作。
、前端总线是被所有的所共享的。这些在开启一个事务之前,必须先进行总线使用权的仲裁。而且,每一个都需要侦听总线上所有的事务,以便维持的一致性。因此,随着部署更多的、多核的处理器到计算机,总线竞争问题会变得越来越严重。为解决这个问题,将处理器直接连接于内存,并以点对点的方式通信,取代之前的广播方式,从而减少总线竞争。
本文讲述的都是有关物理内存请求的重要内容。当涉及到内存锁定、多线程、缓存一致性的问题时,总线这个角色又将浮出水面。当我第一次看到前端总线数据包的描述时,会有种恍然大悟的感觉,所以我希望您也能从本文中获益。下一篇文章,我们将从底层爬回到上层去,研究一个抽象概念:虚拟内存。
[转]: 主板芯片组与内存映射
原文标题:
原文地址:
&& 注:本人水平有限,只好挑一些国外高手的精彩文章翻译一下。一来自己复习,二来与大家分享。
&& 我打算写一组讲述计算机内幕的文章,旨在揭示现代操作系统内核的工作原理。我希望这些文章能对电脑爱好者和程序员有所帮助,特别是对这类话题感兴趣但没有相关知识的人们。讨论的焦点是,,和处理器。钻研系统内幕是我的一个爱好。我曾经编写过不少内核模式的代码,只是最近一段时间不再写了。这第一篇文章讲述了现代主板的布局,如何访问内存,以及系统的内存映射。
&& 作为开始,让我们看看当今的计算机是如何连接各个组件的吧。下图展示了主板上的主要组件:
现代主板的示意图,北桥和南桥构成了芯片组。
&& 当你看图时,请牢记一个至关重要的事实:一点也不知道它连接了什么东西。仅仅通过一组与外界交互,它并不关心外界到底有什么。可能是一个电脑主板,但也可能是烤面包机,网络路由器,植入脑内的设备,或测试工作台。主要通过种方式与外界交互:内存地址空间,地址空间,还有中断。
眼下,我们只关心主板和内存。安装在主板上的与外界沟通的门户是前端总线(),前端总线把与北桥连接起来。每当需要读写内存时,都会使用这条总线。通过一部分管脚来传输想要读写的物理内存地址,同时另一些管脚用于发送将被写入或接收被读出的数据。一个有个针脚用于传输物理内存地址(可以表示个地址位置),个针脚用于接收发送数据(所以数据在位通道中传输,也就是字节的数据块)。这使得可以控制的物理内存(个地址乘以字节),尽管大多数的芯片组只能支持的。
现在到了最难理解的部分。我们可能曾经认为内存指的就是,被各式各样的程序读写着。的确,大部分发出的内存请求都被北桥转送给了管理器,但并非全部如此。物理内存地址还可能被用于主板上各种设备间的通信,这种通信方式叫做。这类设备包括显卡,大多数的卡(比如扫描仪或卡),以及中的存储器等。
&& 当北桥接收到一个物理内存访问请求时,它需要决定把这个请求转发到哪里:是发给?抑或是显卡?具体发给谁是由内存地址映射表来决定的。映射表知道每一个物理内存地址区域所对应的设备。绝大部分的地址被映射到了,其余地址由映射表来通知芯片组该由哪个设备来响应此地址的访问请求。这些被映射为设备的内存地址形成了一个经典的空洞,位于内存的到之间。当内存地址被保留用于显卡和设备时,就会形成更大的空洞。这就是为什么位的操作系统。中,这个文件简明的列举了这些空洞的地址范围。下图展示了低端物理内存地址形成的一个典型的内存映射:
系统中,低端内存地址空间的布局。
实际的地址和范围依赖于特定的主板和电脑中接入的设备,但是对于大多数系统,情形都跟上图非常接近。所有棕色的区域都被设备地址映射走了。记住,这些在主板总线上使用的都是物理地址。在内部(比如我们正在编写和运行的程序),使用的是逻辑地址,必须先由翻译成物理地址以后,才能发布到总线上去访问内存。
这个把逻辑地址翻译成物理地址的规则比较复杂,而且还依赖于当时的运行模式(实模式,位保护模式,位保护模式)。不管采用哪种翻译机制,的运行模式决定了有多少物理内存可以被访问。比如,当工作于位保护模式时,它只可以寻址物理地址空间(当然,也有个例外叫做,但暂且忽略这个技术吧)。由于顶部的大约物理地址被映射到了主板上的设备,实际能够使用的也就只有大约的(有时甚至更少,我曾用过一台安装了的电脑,它只有可用)。如果工作于,那么它将只能寻址的物理地址空间(这是早期的处理器所支持的唯一模式)。如果工作于位保护模式,则可以寻址的地址空间(虽然很少有芯片组支持这么大的)。处于位保护模式时,就有可能访问到空间中被主板上的设备映射走了的区域了(即访问空洞下的)。要达到这种效果,就需要使用比系统中所装载的地址区域更高的地址。这种技术叫做回收,而且还需要芯片组的配合。
这些关于内存的知识将为下一篇文章做好铺垫。下次我们会探讨机器的启动过程:从上电开始,直到准备跳转执行操作系统内核为止。如果你想更深入的学习这些东西,我强烈推荐手册。虽然我列出的都是第一手资料,但手册写得很好很准确。这是一些资料:
?《》描述了一个支持处理器的有代表性的芯片组。这也是本文的主要信息来源。
?《》是一个处理器数据手册。它记载了处理器上每一个管脚的作用(当你把管脚按功能分组后,其实并不算多)。很棒的资料,虽然对有些位的描述比较含糊。
?《》是杰出的文档。它优美的解释了体系结构的各个部分,一点也不会让人感到含糊不清。第一卷和第三卷部很值得一读(别被"卷"字吓倒,每卷都不长,而且您可以选择性的阅读)。
?Pádraig Brady建议我链接到的一篇。确实是个好东西。我本打算把这个链接放到讨论存储器的文章中的,但此处列出的越多越好啦。
转: 计算机的引导过程
原文标题:
原文地址:
&&& 注:本人水平有限,只好挑一些国外高手的精彩文章翻译一下。一来自己复习,二来与大家分享。&
&& 前一篇文章介绍了计算机的,从而为本文设定了一个系统引导阶段的场景。引导()是一个复杂的,充满技巧的,涉及多个阶段,又十分有趣的过程。下图列出了此过程的概要:
引导过程概要
当你按下计算机的电源键后(现在别按!),机器就开始运转了。一旦主板上电,它就会初始化自身的固件芯片组和其他零零碎碎的东西并尝试启动。如果此时出了什么问题(比如坏了或根本没装),那么很可能出现的情况是电脑没有任何动静,除了风扇在转。一些主板会在故障或缺失时发出鸣音提示,但以我的经验,此时大多数机器都会处于僵死状态。一些或其他设备也可能导致机器启动时僵死。对于那些以前工作正常,突然出现这种症状的电脑,一个可能的解决办法是拔除所有不必要的设备。你也可以一次只断开一个设备,从而发现哪个是罪魁祸首。
如果一切正常,就开始运行了。在一个多处理器或多核处理器的系统中,会有一个被动态的指派为引导处理器(简写),用于执行全部的和内核初始化代码。其余的处理器,此时被称为应用处理器(简写),一直保持停机状态直到内核明确激活他们为止。虽然经历了很多年的发展,但他们一直保持着完全的向后兼容性,所以现代的可以表现得跟原先年的完全一样。其实,当上电后,它就是这么做的。在这个基本的上电过程中,处理器工作于,功能是无效的。此时的系统环境,就像古老的一样,只有内存可以寻址,任何代码都可以读写任何地址的内存,这里没有保护或特权级的概念。
上电后,大部分寄存器的都具有定义良好的初始值,包括指令指针寄存器(),它记录了下一条即将被执行的指令所在的内存地址。尽管此时的还只能寻址的内存,但凭借一个奇特的技巧,一个隐藏的基地址(其实就是个偏移量)会与相加,其结果指向第一条将被执行的指令所处的地址(长字节,在内存空间的尾部,远高于)。这个特殊的地址叫做,而且是现代的标准。
主板保证在复位向量处的指令是一个跳转,而且是跳转到执行入口点所在的。这个跳转会顺带清除那个隐藏的、上电时的基地址。感谢芯片组提供的内存映射功能,此时的内存地址存放着初始化所需的真正内容。这些内容全部是从包含有的闪存映射过来的,而此时的模块还只有随机的垃圾数据。下面的图例列出了相关的内存区域:
引导时的重要内存区域
随后,开始执行的代码,初始化机器中的一些硬件。之后开始执行(),检测计算机中的各种组件。如果找不到一个可用的显卡,就会失败,导致进入停机状态并发出鸣音提示(因为此时无法在屏幕上输出提示信息)。如果显卡正常,那么电脑看起来就真的运转起来了:显示一个制造商定制的商标,开始内存自检,天使们大声的吹响号角。另有一些失败的情况,比如缺少键盘,会导致停机,屏幕上显示出错信息。其实即是检测又是初始化,还要枚举出所有设备的资源——中断,内存范围,端口。现代的会遵循()协议,创建一些用于描述设备的数据表,这些表格将来会被操作系统内核用到。
完毕后,就准备引导操作系统了,它必须存在于某个地方:硬盘,光驱,软盘等。搜索引导设备的实际顺序是用户可定制的。如果找不到合适的引导设备,会显示出错信息并停机,比如""没有系统盘或驱动器故障。一个坏了的硬盘可能导致此症状。幸运的是,在这篇文章中,成功的找到了一个可以正常引导的驱动器。
现在,会读取硬盘的第一个(扇区),内含个字节。这些数据叫做(简称)。一般说来,它包含两个极其重要的部分:一个是位于开头的操作系统相关的引导程序,另一个是紧跟其后的磁盘分区表。丝毫不关心这些事情:它只是简单的加载的内容到内存地址处,并跳转到此处开始执行,不管里的代码是什么。
主引导记录
这段在内的特殊代码可能是引导装载程序,引导装载程序(比如或),甚至可能是病毒。与此不同,分区表则是标准化的:它是一个字节的区块,包含个字节的记录项,描述磁盘是如何被分割的(所以你可以在一个磁盘上安装多个操作系统或拥有多个独立的卷)。传统上,的代码会查看分区表,找到一个(唯一的)标记为活动()的分区,加载那个分区的引导扇区(),并执行其中的代码。引导扇区是一个分区的第一个扇区,而不是整个磁盘的第一个扇区。如果此时出了什么问题,你可能会收到如下错误信息:""无效分区表或""操作系统缺失。这条信息不是来自的,而是由从磁盘加载的程序所给出的。因此这些信息依赖于的内容。
随着时间的推移,引导装载过程已经发展得越来越复杂,越来越灵活。的引导装载程序和可以处理很多种类的操作系统,文件系统,以及引导配置信息。他们的代码不再需要效仿上述"从活动分区来引导"的方法。但是从功能上讲,这个过程大致如下:
、MBR本身包含有第一阶段的引导装载程序。称之为阶段一。
、由于很小,其中的代码仅仅用于从磁盘加载另一个含有额外的引导代码的扇区。此扇区可能是某个分区的引导扇区,但也可能是一个被硬编码到中的扇区位置。
、MBR配合第步所加载的代码去读取一个文件,其中包含了下一阶段所需的引导程序。这在中是"阶段二"引导程序,在中是。如果第步失败了,在中你会收到错误信息,比如""缺失。阶段二的代码进一步读取一个引导配置文件(比如在中是,在中是)。之后要么给用户显示一些引导选项,要么直接去引导系统。
、此时,引导装载程序需要启动操作系统核心。它必须拥有足够的关于文件系统的信息,以便从引导分区中读取内核。在中,这意味着读取一个名字类似""的含有内核镜像的文件,将之加载到内存并跳转去执行内核引导代码。在中,一部份内核启动代码是与内核镜像本身分离的,事实上是嵌入到了当中。在完成一些初始化工作以后,从""文件加载内核镜像,就像所做的那样,跳转到内核的入口点去执行。
这里还有一个复杂的地方值得一提(这也是我说引导富于技巧性的原因)。当前内核的镜像就算被压缩了,在实模式下,也没法塞进的可用里。我的内核压缩后有。然而,引导装载程序必须运行于实模式,以便调用代码去读取磁盘,所以此时内核肯定是没法用的。解决之道是使用一种倍受推崇的""。它并非一个真正的处理器运行模式(希望的工程师允许我以此作乐),而是一个特殊技巧。程序不断的在实模式和保护模式之间切换,以便访问高于的内存同时还能使用。如果你阅读了的源代码,你就会发现这些切换到处都是(看看目录下的程序,对和函数的调用)。在这个棘手的过程结束时,装载程序终于千方百计的把整个内核都塞到内存里了,但在这后,处理器仍保持在实模式运行。
至此,我们来到了从"引导装载"跳转到"早期的内核初始化"的时刻,就像第一张图中所指示的那样。在系统做完热身运动后,内核会展开并让系统开始运转。下一篇文章将带大家一步步深入内核的初始化过程,读者还可以参考的资源。我没办法对也这么做,但我会把要点指出来。
转: 内核引导过程
原文标题:
原文地址:
&& 注:本人水平有限,只好挑一些国外高手的精彩文章翻译一下。一来自己复习,二来与大家分享。
&& 上一篇文章解释了计算机的,正好讲到引导装载程序把系统内核镜像塞进内存,准备跳转到内核入口点去执行的时刻。作为引导启动系列文章的最后一篇,就让我们深入内核,去看看操作系统是怎么启动的吧。由于我习惯以事实为依据讨论问题,所以文中会出现大量的链接引用内核版的源代码(源自)。如果你熟悉的语法,这些代码就会非常容易读懂;即使你忽略一些细节,仍能大致明白程序都干了些什么。最主要的障碍在于对一些代码的理解需要相关的背景知识,比如机器的底层特性或什么时候、为什么它会运行。我希望能尽量给读者提供一些背景知识。为了保持简洁,许多有趣的东西,比如中断和内存,文中只能点到为止了。在本文的最后列出了的引导过程的要点。
&& 当的引导程序运行到此刻时,处理器处于实模式(可以寻址的内存),(针对现代的系统)的内容大致如下:
引导装载完成后的内容
&& 引导装载程序通过的磁盘服务,已经把内核镜像加载到内存当中。这个镜像只是硬盘中内核文件(比如)的一份完全相同的拷贝。镜像分为两个部分:一个较小的部分,包含实模式的内核代码,被加载到内存边界以下;另一部分是一大块内核,运行在保护模式,被加载到低端内存地址以上。
&& 如上图所示,之后的事情发生在实模式内核的头部()。这段内存区域用于实现引导装载程序与内核之间的引导协议。此处的一些数据会被引导装载程序读取。这些数据包括一些令人愉快的信息,比如包含内核版本号的可读字符串,也包括一些关键信息,比如实模式内核代码的大小。引导装载程序还会向这个区域写入数据,比如用户选中的引导菜单项对应的命令行参数所在的内存地址。之后就到了跳转到内核入口点的时刻。下图显示了内核初始化代码的执行顺序,包括源代码的目录、文件和行号:
与体系结构相关的内核初始化过程
对于体系结构,内核启动前期会执行文件中的程序。它是用汇编语言书写的。一般说来汇编代码在内核中很少出现,但常见于引导代码。这个文件的开头实际上包含了引导扇区代码。早期的不需要引导装载程序就可以工作,这段代码是从那个时候留传下来的。现今,如果这个引导扇区被执行,它仅仅给用户输出一个""之后就会重启系统。现代的引导装载程序会忽略这段遗留代码。在引导扇区代码之后,我们会看到实模式内核头部()最开始的字节;这两部分合起来是字节,正好是硬件平台上一个典型的磁盘扇区的大小。
&& 在这字节之后,偏移量处,我们会发现内核的第一条指令,也就是实模式内核的入口点。具体的说,它在,是一个字节的跳转指令,直接写成了机器码的形式。你可以通过对内核镜像运行,并查看偏移量处的内容来验证这一点——这仅仅是一个对神志清醒程度的检查,以确保这一切并不是在做梦。引导装载程序运行完毕时就会跳转执行这个位置的指令,进而跳转到执行一个普通的用汇编写成的子程序,叫做。这个短小的子程序初始化栈空间(),把实模式内核的段清零(这个区域包含静态变量,所以用来初始化它们),之后跳转执行一段又老又好的语言程序:。
&& 会处理一些登记工作(比如检测内存布局),设置显示模式等。然后它会调用。然而,在把置于保护模式之前,还有一些工作必须完成。有两个主要问题:中断和内存。在实模式中,处理器的总是从内存的地址开始的,然而在保护模式中,这个中断向量表的位置是保存在一个叫的寄存器当中的。与此同时,从逻辑内存地址(在程序中使用)到线性内存地址(一个从连续编号到内存顶端的数值)的翻译方法在实模式和保护模式中是不同的。保护模式需要一个叫做的寄存器来存放内存的地址。所以调用了 和,用于装载临时的中断描述符表和全局描述符表。
现在我们可以转入保护模式啦,这是由另一段汇编子程序来完成的。这个子程序通过设定的寄存器的位来使能保护模式。此时,功能还处于关闭状态;分页是处理器的一个可选的功能,即使运行于保护模式也并非必要。真正重要的是,我们不再受制于的内存边界,现在可以寻址高达的了。这个子程序进而调用压缩状态内核的位内核入口点。会做一些简单的寄存器初始化工作,并调用一个语言编写的函数,用于实际的解压缩工作。
&& 会打印一条大家熟悉的信息""(正在解压缩)。解压缩过程是原地进行的,一旦完成内核镜像的解压缩,第一张图中所示的压缩内核镜像就会被覆盖掉。因此解压后的内核也是从位置开始的。之后,会显示""(完成)和令人振奋的""(正在引导内核)。这里""的意思是跳转到整个故事的最后一个入口点,也是保护模式内核的入口点,位于的第二个开始处(偏移量,此值是由芬兰山巅之上的神灵授意给的)。在这个神圣的位置含有一个子程序调用,名叫呃。但你会发现这一位是在另一个目录中的。
这位的第二个化身也是一个汇编子程序,但它包含了位模式的初始化过程:
、它清理了保护模式内核的段。(这回是真正的内核了,它会一直运行,直到机器重启或关机。)
、为内存建立最终的全局描述符表。
、建立页表以便可以开启分页功能。
、使能分页功能。
、初始化栈空间。
、创建最终的中断描述符表。
、最后,跳转执行一个体系结构无关的内核启动函数:。
下图显示了引导最后一步的代码执行流程:
与体系结构无关的内核初始化过程
&& 看起来更像典型的内核代码,几乎全用语言编写而且与特定机器无关。这个函数调用了一长串的函数,用来初始化各个内核子系统和数据结构,包括调度器(),内存分区(),计时器()等等。之后,调用,此时几乎所有的东西都可以工作了。会创建一个内核线程,并以另一个函数作为此线程的入口点。之后,会调用来激活任务调度功能,然后调用使自己进入睡眠()状态,成为内核中的一个空闲线程()。会在号进程()中永远的运行下去。一旦有什么事情可做,比如有了一个活动就绪的进程(),号进程就会激活去执行这个任务,直到没有活动就绪的进程后才返回。
&& 但是,还有一个小麻烦需要处理。我们跟随引导过程一路走下来,这个漫长的线程以一个空闲循环()作为结尾。处理器上电执行第一条跳转指令以后,一路运行,最终会到达此处。从复位向量()引导装载程序实模式内核保护模式内核,跳转跳转再跳转,经过所有这些杂七杂八的步骤,最后来到引导处理器()中的空闲循环。看起来真的很酷。然而,这并非故事的全部,否则计算机就不会工作。
&& 在这个时候,前面启动的那个内核线程已经准备就绪,可以取代号进程和它的空闲线程了。事实也是如此,就发生在开始运行的时刻(此函数之前被作为线程的入口点)。的职责是初始化系统中其余的,这些从引导过程开始到现在,还一直处于停机状态。之前我们看过的所有代码都是在一个单独的上运行的,它叫做引导处理器()。当其他——称作应用处理器()——启动以后,它们是处于实模式的,必须通过一些初始化步骤才能进入保护模式。大部分的代码过程都是相同的,你可以参考,但对于应用处理器,还是有些细微的不同。最终,会调用,后者会尝试启动一个用户模式()的进程,尝试的顺序为:,,,。如果都不行,内核就会报错。幸运的是经常就在这些地方的,于是号进程()就开始运行了。它会根据对应的配置文件来决定启动哪些进程,这可能包括,控制台登陆程序,网络后台程序等。从而结束了引导进程,同时另一个程序开始在某处运行。至此,让我祝福您的电脑可以一直正常运行下去,不出毛病。
&& 在同样的体系结构下,的启动过程与有很多相似之处。它也面临同样的问题,也必须完成类似的初始化过程。当引导过程开始后,一个最大的不同是,把全部的实模式内核代码以及一部分初始的保护模式代码都打包到了引导加载程序(:)当中。因此,使用的二进制镜像文件就不一样了,内核镜像中没有包含两个部分的代码。另外,把引导装载程序与内核完全分离,在某种程度上自动的形成不同的开源项目。下图显示了内核主要的启动过程:
内核初始化过程
&& 自然而然的,用户模式的启动就非常不同了。没有程序,而是运行和。会启动(它会启动所有的服务程序)、和本地安全认证子系统。经典的登陆对话框就是运行在的上下文中的。
&& 本文是引导启动系列话题的最后一篇。感谢每一位读者,感谢你们的反馈。我很抱歉,有些内容只能点到为止;我打算把它们留在其他文章中深入讨论,并尽量保持文章的长度适合的风格。下次我打算定期的撰写关于""的文章,就像本系列一样。最后,给大家一些参考资料:
?最好也最重要的资料是实际的内核代码,或的都成。
?Intel出版的杰出的,你可以免费下载到。
?《内核》是本好书,其中讨论了大量的内核代码。这书也许有点过时有点枯燥,但我还是将它推荐给那些想要与内核心意相通的人们。《设备驱动程序》读起来会有趣得多,讲的也不错,但是涉及的内容有些局限性。最后,网友推荐所写的《内核开发》,我曾听过一些对此书的正面评价,所以还是值得列出来的。
?对于,目前最好的参考书是《》,作者是和,后者是的知名专家。这是本特棒的书,写的很好而且讲解全面。主要的缺点是缺少源代码的支持。
转: 内存地址转换与分段
原文标题:
原文地址:
&& 注:本人水平有限,只好挑一些国外高手的精彩文章翻译一下。一来自己复习,二来与大家分享。
&& 本文是兼容计算机()的内存与保护系列文章的第一篇,延续了系列文章的主题,进一步分析操作系统内核的工作流程。与以前一样,我将引用内核的源代码,但对只给出示例(抱歉,我忽略了,等系统,但大部分的讨论对它们一样适用)。文中如果有错误,请不吝赐教。
在支持的上,对内存的访问是通过连接着和北桥芯片的前端总线来完成的。在前端总线上传输的内存地址都是物理内存地址,编号从开始一直到可用物理内存的最高端。这些数字被北桥映射到实际的内存条上。物理地址是明确的、最终用在总线上的编号,不必转换,不必分页,也没有特权级检查。然而,在内部,程序所使用的是逻辑内存地址,它必须被转换成物理地址后,才能用于实际内存访问。从概念上讲,地址转换的过程如下图所示:
开启分页功能后的内存地址转换过程
此图并未指出详实的转换方式,它仅仅描述了在的分页功能开启的情况下内存地址的转换过程。如果关闭了分页功能,或运行于位实模式,那么从分段单元()输出的就是最终的物理地址了。当要执行一条引用了内存地址的指令时,转换过程就开始了。第一步是把逻辑地址转换成线性地址。但是,为什么不跳过这一步,而让软件直接使用线性地址(或物理地址呢?)其理由与:"人类为何要长有阑尾?它的主要作用仅仅是被感染发炎而已"大致相同。这是进化过程中产生的奇特构造。要真正理解分段功能的设计,我们就必须回溯到年。
最初的处理器的寄存器是位的,其指令集大多使用位或位的操作数。这使得代码可以控制个字节(或)的内存。然而的工程师们想要让可以使用更多的内存,而又不用扩展寄存器和指令的位宽。于是他们引入了段寄存器(),用来告诉一条程序指令将操作哪一个的内存区块。一个合理的解决方案是:你先加载段寄存器,相当于说"这儿!我打算操作开始于处的内存区块";之后,再用位的内存地址来表示相对于那个内存区块(或段)的偏移量。总共有个段寄存器:一个用于栈(),一个用于程序代码(),两个用于数据(,)。在那个年代,大部分程序的栈、代码、数据都可以塞进对应的段中,每段长,所以分段功能经常是透明的。
&& 现今,分段功能依然存在,一直被处理器所使用着。每一条会访问内存的指令都隐式的使用了段寄存器。比如,一条跳转指令会用到代码段寄存器(),一条压栈指令()会使用到堆栈段寄存器()。在大部分情况下你可以使用指令明确的改写段寄存器的值。段寄存器存储了一个位的段选择符();它们可以经由机器指令(比如)被直接加载。唯一的例外是代码段寄存器(),它只能被影响程序执行顺序的指令所改变,比如或指令。虽然分段功能一直是开启的,但其在实模式与保护模式下的运作方式并不相同的。
&& 在实模式下,比如在,段选择符是一个位的数值,指示出一个段的开始处的物理内存地址。这个数值必须被以某种方式放大,否则它也会受限于当中,分段就没有意义了。比如,可能会把这个段选择符当作物理内存地址的高位(只需将之左移位,也就是乘以)。这个简单的规则使得:可以按的段为单位,一块块的将的内存都寻址到。遗憾的是,做了一个很诡异的设计,让段选择符仅仅乘以(或),一举将寻址范围限制在了,还引入了过度复杂的转换过程。下述图例显示了一条跳转指令,的值是:
实模式分段功能
实模式的段地址以个字节为步长,从开始编号一直到(即)。你可以将一个从到的位偏移量(逻辑地址)加在段地址上。在这个下,对于同一个内存地址,会有多个段地址偏移量的组合与之对应,而且物理地址可以超过的边界,只要你的段地址足够高(参见臭名昭著的线)。同样的,在实模式的语言代码中,一个()既包含了段选择符又包含了逻辑地址,用于寻址的内存范围。真够"远"的啊。随着程序变得越来越大,超出了的段,分段功能以及它古怪的处理方式,使得平台的软件开发变得非常复杂。这种设定可能听起来有些诡异,但它却把当时的程序员推进了令人崩溃的深渊。
在位保护模式下,段选择符不再是一个单纯的数值,取而代之的是一个索引编号,用于引用段描述符表中的表项。这个表为一个简单的数组,元素长度为字节,每个元素描述一个段。看起来如下:
有三种类型的段:代码,数据,系统。为了简洁明了,只有描述符的共有特征被绘制出来。基地址()是一个位的线性地址,指向段的开始;段界限()指出这个段有多大。将基地址加到逻辑地址上就形成了线性地址。是描述符的特权级(),其值从(最高特权,内核模式)到(最低特权,用户模式),用于控制对段的访问。
这些段描述符被保存在两个表中:全局描述符表()和局部描述符表()。电脑中的每一个(或一个处理核心)都含有一个叫做的寄存器,用于保存的首个字节所在的线性内存地址。为了选出一个段,你必须向段寄存器加载符合以下格式的段选择符:
对,位为;对,位为;指出想要表中哪一个段描述符(译注:原文是段选择符,应该是笔误)。对于,请求特权级(),以后我们还会详细讨论。现在,需要好好想想了。当运行于位模式时,不管怎样,寄存器和指令都可以寻址整个线性地址空间,所以根本就不需要再去使用基地址或其他什么鬼东西。那为什么不干脆将基地址设成,好让逻辑地址与线性地址一致呢?的文档将之称为"扁平模型"(),而且在现代的系统内核中就是这么做的(特别指出,它们使用的是基本扁平模型)。基本扁平模型()等价于在转换地址时关闭了分段功能。如此一来多么美好啊。就让我们来看看位保护模式下执行一个跳转指令的例子,其中的数值来自一个实际的用户模式应用程序:
保护模式的分段
段描述符的内容一旦被访问,就会被(缓存),所以在随后的访问中,就不再需要去实际读取了,否则会有损性能。每个段寄存器都有一个隐藏部分用于缓存段选择符所对应的那个段描述符。如果你想了解更多细节,包括关于的更多信息,请参阅《》卷的第三章。和卷讲述了每一个指令,同时也指明了寻址时所使用的各种类型的操作数:位,位加段描述符(可被用于实现远指针),位,等等。
在上,只有个段描述符在引导启动过程被使用。他们使用宏来定义并存储在数组中。其中两个段是扁平的,可对整个位空间寻址:一个是代码段,加载到中,一个是数据段,加载到其他段寄存器中。第三个段是系统段,称为任务状态段()。在完成引导启动以后,每一个都拥有一份属于自己的。其中大部分内容是相同的,只有少数表项依赖于正在运行的进程。你可以从看到的布局以及其。这里有个主要的表项:个是扁平的,用于内核模式的代码和数据,另两个用于用户模式。在看这个时,请留意那些用于确保数据与缓存线对齐的填充字节——目的是克服。最后要说说,那个经典的错误信息""(分段错误)并不是由风格的段所引起的,而是由于分页单元检测到了非法的内存地址。唉呀,下次再讨论这个话题吧。
巧妙的绕过了他们原先设计的那个拼拼凑凑的分段方法,而是提供了一种富于弹性的方式来让我们选择是使用段还是使用扁平模型。由于很容易将逻辑地址与线性地址合二为一,于是这成为了标准,比如现在在位模式中就强制使用扁平的线性地址空间了。但是即使是在扁平模型中,段对于的保护机制也十分重要。保护机制用于抵御用户模式进程对系统内核的非法内存访问,或各个进程之间的非法内存访问,否则系统将会进入一个狗咬狗的世界!在下一篇文章中,我们将窥视保护级别以及如何用段来实现这些保护功能。
转: CPU的运行环, 特权级与保护
原文标题:
原文地址:
&& 注:本人水平有限,只好挑一些国外高手的精彩文章翻译一下。一来自己复习,二来与大家分享。
&& 可能你凭借直觉就知道应用程序的功能受到了计算机的某种限制,有些特定的任务只有操作系统的代码才可以完成,但是你知道这到底是怎么一回事吗?在这篇文章里,我们会接触到的特权级(),看看操作系统和是怎么一起合谋来限制用户模式的应用程序的。特权级总共有个,编号从(最高特权)到(最低特权)。有种主要的资源受到保护:内存,端口以及执行特殊机器指令的能力。在任一时刻,都是在一个特定的特权级下运行的,从而决定了代码可以做什么,不可以做什么。这些特权级经常被描述为保护环(),最内的环对应于最高特权。即使是最新的内核也只用到其中的个特权级:和。
&& 在诸多机器指令中,只有大约条指令被限制只能在执行(其余那么多指令的操作数都受到一定的限制)。这些指令如果被用户模式的程序所使用,就会颠覆保护机制或引起混乱,所以它们被保留给内核使用。如果企图在以外运行这些指令,就会导致一个一般保护错(),就像一个程序使用了非法的内存地址一样。类似的,对内存和端口的访问也受特权级的限制。但是,在我们分析保护机制之前,先让我们看看是怎么记录当前特权级的吧,这与前篇文章中提到的()有关。如下所示:
数据段和代码段的段选择符
数据段选择符的整个内容可由程序直接加载到各个段寄存器当中,比如(堆栈段寄存器)和(数据段寄存器)。这些内容里包含了请求特权级(,简称)字段,其含义过会儿再说。然而,代码段寄存器()就比较特别了。首先,它的内容不能由装载指令(如)直接设置,而只能被那些会改变程序执行顺序的指令(如)间接的设置。而且,不像那个可以被代码设置的字段,拥有一个由自己维护的当前特权级字段(,简称),这点对我们来说非常重要。这个代码段寄存器中的位宽的字段的值总是等于的当前特权级。的文档并未明确指出此事实,而且有时在线文档也对此含糊其辞,但这的确是个硬性规定。在任何时候,不管内部正在发生什么,只要看一眼中的,你就可以知道此刻的特权级了。
记住,特权级并不会对操作系统的用户造成什么影响,不管你是根用户,管理员,访客还是一般用户。所有的用户代码都在上执行,所有的内核代码都在上执行,跟是以哪个用户的身份执行无关。有时一些内核任务可以被放到用户模式中执行,比如上的用户模式驱动程序,但是它们只是替内核执行任务的特殊进程而已,而且往往可以被直接删除而不会引起严重后果。
由于限制了对内存和端口的访问,用户模式代码在不调用系统内核的情况下,几乎不能与外部世界交互。它不能打开文件,发送网络数据包,向屏幕打印信息或分配内存。用户模式进程的执行被严格限制在一个由之神所设定的沙盘之中。这就是为什么从设计上就决定了:一个进程所泄漏的内存会在进程结束后被统统回收,之前打开的文件也会被自动关闭。所有的控制着内存或打开的文件等的数据结构全都不能被用户代码直接使用;一旦进程结束了,这个沙盘就会被内核拆毁。这就是为什么我们的服务器只要硬件和内核不出毛病,就可以连续正常运行天,甚至一直运行下去。这也解释了为什么那么容易死机:这并非因为微软差劲,而是因为系统中的一些重要数据结构,出于兼容的目的被设计成可以由用户直接访问了。这在当时可能是一个很好的折中,当然代价也很大。
会在两个关键点上保护内存:当一个段选择符被加载时,以及,当通过线形地址访问一个内存页时。因此,保护也反映在的过程之中,既包括分段又包括分页。当一个数据段选择符被加载时,就会发生下述的检测过程:
的分段保护
因为越高的数值代表越低的特权,上图中的用于挑出和中特权最低的一个,并与描述符特权级(,简称)比较。如果的值大于等于它,那么这个访问就获得许可了。背后的设计思想是:允许内核代码加载特权较低的段。比如,你可以使用的段描述符来确保给定的操作所使用的段可以在用户模式中访问。但堆栈段寄存器是个例外,它要求,和这个值必须完全一致,才可以被加载。
事实上,段保护功能几乎没什么用,因为现代的内核使用扁平的地址空间。在那里,用户模式的段可以访问整个线形地址空间。真正有用的内存保护发生在分页单元中,即从线形地址转化为物理地址的时候。一个内存页就是由一个页表项()所描述的字节块。页表项包含两个与保护有关的字段:一个超级用户标志(),一个读写标志()。超级用户标志是内核所使用的重要的内存保护机制。当它开启时,内存页就不能被访问了。尽管读写标志对于实施特权控制并不像前者那么重要,但它依然十分有用。当一个进程被加载后,那些存储了二进制镜像(即代码)的内存页就被标记为只读了,从而可以捕获一些指针错误,比如程序企图通过此指针来写这些内存页。这个标志还被用于在调用创建子进程时,实现写时拷贝功能()。
&& 最后,我们需要一种方式来让切换它的特权级。如果的程序可以随意的将控制转移到(即跳转到)内核的任意位置,那么一个错误的跳转就会轻易的把操作系统毁掉了。但控制的转移是必须的。这项工作是通过门描述符()和指令来完成的。一个门描述符就是一个系统类型的段描述符,分为了个子类型:调用门描述符(),中断门描述符(),陷阱门描述符()和任务门描述符()。调用门提供了一个可以用于通常的和指令的内核入口点,但是由于调用门用得不多,我就忽略不提了。任务门也不怎么热门(在上,它们只在处理内核或硬件问题引起的双重故障时才被用到)。
&& 剩下两个有趣的:中断门和陷阱门,它们用来处理硬件中断(如键盘,计时器,磁盘)和异常(如缺页异常,除数异常)。我将不再区分中断和异常,在文中统一用"中断"一词表示。这些门描述符被存储在中断描述符表(,简称)当中。每一个中断都被赋予一个从到的编号,叫做中断向量。处理器把中断向量作为表项的索引,用来指出当中断发生时使用哪一个门描述符来处理中断。中断门和陷阱门几乎是一样的。下图给出了它们的格式。以及当中断发生时实施特权检查的过程。我在其中填入了一些内核的典型数值,以便让事情更加清晰具体。
伴随特权检查的中断描述符
&& 门中的和段选择符一起控制着访问,同时,段选择符结合偏移量()指出了中断处理代码的入口点。内核一般在门描述符中填入内核代码段的段选择符。一个中断永远不会将控制从高特权环转向低特权环。特权级必须要么保持不变(当内核自己被中断的时候),或被提升(当用户模式的代码被中断的时候)。无论哪一种情况,作为结果的必须等于目的代码段的。如果发生了改变,一个堆栈切换操作就会发生。如果中断是被程序中的指令所触发的(比如),还会增加一个额外的检查:门的必须具有与相同或更低的特权。这就防止了用户代码随意触发中断。如果这些检查失败,正如你所猜测的,会产生一个一般保护错()。所有的中断处理器都以特权退出。
&& 在初始化阶段,内核首先在中建立,并忽略全部中断。之后它使用的函数来填充普通的表项(参见)。在代码中,名字中包含""字样的门描述符是可以从用户模式中访问的,而且其设置函数使用。""是的陷阱门,也可以从用户模式访问。除此之外,术语名词都与本文对得上号。然而,硬件中断门并不是在这里设置的,而是由适当的驱动程序来完成。
&& 有三个门可以被用户模式访问:中断向量和分别用于调试和检查数值运算溢出。剩下的是一个系统门,被设置为。对于体系结构,它等于。它曾被作为一种机制,用于将进程的控制转移到内核,进行一个系统调用(),然后再跳转回来。在那个时代,我需要去申请""这个没用的牌照J。从奔腾开始,引入了指令,从此可以用这种更快捷的方式来启动系统调用了。它依赖于上的特殊目的寄存器,这些寄存器存储着代码段、入口点及内核系统调用处理器所需的其他零散信息。在执行后,不再进行特权检查,而是直接进入,并将新值加载到与代码和堆栈有关的寄存器当中(,,和)。只有的代码可以加载设置寄存器。
&& 最后,当需要跳转回时,内核发出一个或指令,分别用于从中断和系统调用中返回,从而离开并恢复的用户代码的执行。噢!提示我已经接近字了,所以端口的保护只能下次再谈了。这样我们就结束了的运行环与保护之旅。感谢您的耐心阅读。
转: Cache: 一个隐藏并保存数据的场所
原文标题:
原文地址:
&& 注:本人水平有限,只好挑一些国外高手的精彩文章翻译一下。一来自己复习,二来与大家分享。
&& 本文简要的展示了现代处理器的是如何组织的。有关的讨论往往缺乏具体的实例,使得一些简单的概念变得扑朔迷离。也许是我可爱的小脑瓜有点迟钝吧,但不管怎样,至少下面讲述了故事的前一半,即的是如何被访问的:
,路组相联,字节缓存线
&&&&&& 由索引拣选缓存组(行)
&& 在中的数据是以缓存线()为单位组织的,一条缓存线对应于内存中一个连续的字节块。这个使用了字节的缓存线。这些线被保存在中,也叫路()。每一路都有一个专门的目录()用来保存一些登记信息。你可以把每一路连同它的目录想象成电子表格中的一列,而表的一行构成了的一组()。列中的每一个单元()都含有一条缓存线,由与之对应的目录单元跟踪管理。图中的有组、每组路,因此有个含有缓存线的单元,合计的存储空间。
&& 在眼中,物理内存被分割成了许多大小的物理内存页()。每一页都含有条缓存线。在一个的页中,第到字节是第一条缓存线,第到字节是第二条缓存线,以此类推。每一页都重复着这种划分,所以第页第条缓存线与第页第条缓存线是不同的。
&& 在全相联缓存()中,内存中的任意一条缓存线都可以被存储到任意的缓存单元中。这种存储方式十分灵活,但也使得要访问它们时,检索缓存单元的工作变得复杂、昂贵。由于和工作在很强的约束之下,包括功耗,芯片物理空间,存取速度等,所以在多数情况下,使用全相联缓存并不是一个很好的折中。
&& 取而代之的是图中的组相联缓存()。意思是,内存中一条给定的缓存线只能被保存在一个特定的组(或行)中。所以,任意物理内存页的第条缓存线(页内第到字节)必须存储到第组,第条缓存线存储到第组,以此类推。每一组有个单元可用于存储它所关联的缓存线(译注:就是那些需要存储到这一组的缓存线),从而形成一个路关联的组()。当访问一个内存地址时,地址的第到位(译注:组索引)指出了在内存页中缓存线的编号,从而决定了即将使用的缓存组。举例来说,物理地址的组索引是,所以此地址的内容一定是在第组中缓存的。
&& 但是还有一个问题,就是要找出一组中哪个单元包含了想要的信息,如果有的话。这就到了缓存目录登场的时刻。每一个缓存线都被其对应的目录单元做了标记();这个标记就是一个简单的内存页编号,指出缓存线来自于哪一页。由于处理器可以寻址的物理,所以总共有个内存页,需要位来保存标记。前例中的物理地址对应的页号为。下面是故事的后一半:
在组中搜索匹配标记
&& 由于我们只需要去查看某一组中的路,所以查找匹配标记是非常迅速的;事实上,从电学角度讲,所有的标记是同时进行比对的,我用箭头来表示这一点。如果此时正好有一条具有匹配标签的有效缓存线,我们就获得一次缓存命中()。否则,这个请求就会被转发的,如果还没匹配上就再转发给主系统内存。通过应用各种调节尺寸和容量的技术,给配置了较大的,但其基本的设计都是相同的。比如,你可以将原先的缓存增加路而获得一个的缓存;再将组数增加到,每路可以存储。经过这两次修改,就得到了一个的。在此情况下,需要位来保存标记,位保存组索引;缓存所使用的物理内存页的大小与其一路的大小相等。(译注:有组,就需要位的组索引,缓存线依然是字节,所以一路有字节;在眼中,内存被分割为许多的块,所以需要位来保存标记。)
&& 如果有一组已经被放满了,那么在另一条缓存线被存储进来之前,已有的某一条则必须被腾空()。为了避免这种情况,对运算速度要求较高的程序就要尝试仔细组织它的数据,使得内存访问均匀的分布在已有的缓存线上。举例来说,假设程序中有一个数组,元素的大小是字节,其中一些对象在内存中相距。这些对象的各个字段都落在同一缓存线上,并竞争同一缓存组。如果程序频繁的访问一个给定的字段(比如,通过调用虚函数),那么这个组看起来就好像一直是被填满的,缓存开始变得毫无意义,因为缓存线一直在重复着腾空与重新载入的步骤。在我们的例子中,由于组数的限制,仅能保存个这类对象的虚函数表。这就是组相联策略的折中所付出的代价:即使在整体缓存的使用率并不高的情况下,由于组冲突,我们还是会遇到缓存缺失的情况。然而,鉴于计算机中各个存储层次的,不管怎么说,大部分的应用程序并不必为此而担心。
一个内存访问经常由一个线性(或虚拟)地址发起,所以需要依赖分页单元()来求出物理内存页的地址,以便用于缓存标记。与此相反,组索引来自于线性地址的低位,所以不需要转换就可以使用了(在我们的例子中为第到位)。因此是物理标记但虚拟索引的(),从而帮助进行并行的查找操作。因为的一路绝不会比的一页还大,所以可以保证一个给定的物理地址位置总是关联到同一组,即使组索引是虚拟的。在另一方面必须是物理标记和物理索引的,因为它的一路比的一页要大。但是,当一个请求到达时,物理地址已经被准备()完毕了,所以会工作得很好。
最后,目录单元还存储了对应缓存线的状态()。在代码缓存中的一条缓存线要么是无效的()要么是共享的(,意思是有效的,真的J)。在数据缓存和缓存中,一条缓存线可以为个状态之一:被修改的(),独占的(),共享的(),无效的()。缓存是包容式的():缓存的内容会被复制到缓存中。在下一篇讨论线程(),锁定()等内容的文章中,这些缓存线状态将发挥作用。下一次,我们将看看前端总线以及内存访问到底是怎么工作的。这将成为一个内存研讨周。
(在回复中提到了直接映射缓存()。它们基本上是一种特殊的组相联缓存,只是只有一路而已。在各种折中方案中,它与全相联缓存正好相反:访问非常快捷,但因组冲突而导致的缓存缺失也非常多。)
译者小结:
&&&&&&&& 内存层次结构的意义在于利用引用的空间局部性和时间局部性原理,将经常被访问的数据放到快速的存储器中,而将不经常访问的数据留在较慢的存储器中。
&&&&&&&& 一般情况下,除了寄存器和缓存可以操作指定字长的数据,下层的内存子系统就不会再使用这么小的单位了,而是直接移动数据块,比如以缓存线为单位访问数据。
&&&&&&&& 对于组冲突,可以这么理解:与上文相似,假设一个缓存,由条缓存线组成,每条线字节,容量。
&&&&&&&& 假如它是直接映射缓存,由于它往往使用地址的低位直接映射缓存线编号,所以所有的倍数的地址(,,等)都会映射到同一条线上(即第线)。假如程序的内存组织不当,交替的去访问布置在这些地址的数据,则会导致冲突。从外表看来就好像缓存只有条线了,尽管其他缓存线一直是空闲着的。
&&&&&&& 如果是全相联缓存,那么每条缓存线都是独立的,可以对应于内存中的任意缓存线。只有当所有的条缓存线都被占满后才会出现冲突。
&&&&&&& 组相联是前两者的折中,每一路中的缓存线采用直接映射方式,而在路与路之间,缓存控制器使用全相联映射算法,决定选择一组中的哪一条线。
&&&&&&& 如果是路组相联缓存,那么这条缓存线就被分为了路,每路条线,一路。此时所有为整数倍的地址(,,等)都会映射到第线,但由于路是关联的,所以可以同时有个这种地址的内容被缓存,不会发生冲突。当然了,如果要访问第三个这种地址,还是要先腾空已有的一条才行。所以极端情况下,从外表看来就好像缓存只有条线了,尽管其他缓存线一直是空闲着的。
&&&&&&&& 如果是路组相联缓存(与文中示例相同),那么这条缓存线就被分为了路,每路条线,一路。所以如果数组中元素地址是对齐的,并且程序交替的访问这些元素,就会出现组冲突。从外表看来就好像缓存只有条线了,尽管其他缓存线一直是空闲着的。
转: 剖析程序的内存布局
原文标题:
原文地址:
&& 注:本人水平有限,只好挑一些国外高手的精彩文章翻译一下。一来自己复习,二来与大家分享。
&& 内存管理模块是操作系统的心脏;它对应用程序和系统管理非常重要。今后的几篇文章中,我将着眼于实际的内存问题,但也不避讳其中的技术内幕。由于不少概念是通用的,所以文中大部分例子取自位平台的和系统。本系列第一篇文章讲述应用程序的内存布局。
&& 在多任务操作系统中的每一个进程都运行在一个属于它自己的内存沙盘中。这个沙盘就是虚拟地址空间(),在位模式下它总是一个的内存地址块。这些虚拟地址通过页表()映射到物理内存,页表由操作系统维护并被处理器引用。每一个进程拥有一套属于它自己的页表,但是还有一个隐情。只要虚拟地址被使能,那么它就会作用于这台机器上运行的所有软件,包括内核本身。因此一部分虚拟地址必须保留给内核使用:
这并不意味着内核使用了那么多的物理内存,仅表示它可支配这么大的地址空间,可根据内核需要,将其映射到物理内存。内核空间在页表中拥有较高的(或以下),因此只要用户态的程序试图访问这些页,就会导致一个页错误()。在中,内核空间是持续存在的,并且在所有进程中都映射到同样的物理内存。内核代码和数据总是可寻址的,随时准备处理中断和系统调用。与此相反,用户模式地址空间的映射随进程切换的发生而不断变化:
蓝色区域表示映射到物理内存的虚拟地址,而白色区域表示未映射的部分。在上面的例子中,使用了相当多的虚拟地址空间,因为它是传说中的吃内存大户。地址空间中的各个条带对应于不同的内存段(),如:堆、栈之类的。记住,这些段只是简单的内存地址范围,与处理器的段没有关系。不管怎样,下面是一个进程的标准的内存段布局:
当计算机开心、安全、可爱、正常的运转时,几乎每一个进程的各个段的起始虚拟地址都与上图完全一致,这也给远程发掘程序安全漏洞打开了方便之门。一个发掘过程往往需要引用绝对内存地址:栈地址,库函数地址等。远程攻击者必须依赖地址空间布局的一致性,摸索着选择这些地址。如果让他们猜个正着,有人就会被整了。因此,地址空间的随机排布方式逐渐流行起来。通过对、、的起始地址加上随机的偏移量来打乱布局。不幸的是,位地址空间相当紧凑,给随机化所留下的空当不大,。
进程地址空间中最顶部的段是栈,大多数编程语言将之用于存储局部变量和函数参数。调用一个方法或函数会将一个新的栈桢()压入栈中。栈桢在函数返回时被清理。也许是因为数据严格的遵从的顺序,这个简单的设计意味着不必使用复杂的数据结构来追踪栈的内容,只需要一个简单的指针指向栈的顶端即可。因此压栈()和退栈()过程非常迅速、准确。另外,持续的重用栈空间有助于使活跃的栈内存保持在缓存中,从而加速访问。进程中的每一个线程都有属于自己的栈。
&& 通过不断向栈中压入的数据,超出其容量就有会耗尽栈所对应的内存区域。这将触发一个页故障(),并被的处理,它会调用来检查是否还有合适的地方用于栈的增长。如果栈的大小低于(通常是),那么一般情况下栈会被加长,程序继续愉快的运行,感觉不到发生了什么事情。这是一种将栈扩展至所需大小的常规机制。然而,如果达到了最大的栈空间大小,就会栈溢出(),程序收到一个段错误()。当映射了的栈区域扩展到所需的大小后,它就不会再收缩回去,即使栈不那么满了。这就好比联邦预算,它总是在增长的。
&& 动态栈增长是唯一一种访问未映射内存区域(图中白色区域)而被允许的情形。其它任何对未映射内存区域的访问都会触发页故障,从而导致段错误。一些被映射的区域是只读的,因此企图写这些区域也会导致段错误。
&& 在栈的下方,是我们的内存映射段。此处,内核将文件的内容直接映射到内存。任何应用程序都可以通过的系统调用()或的请求这种映射。内存映射是一种方便高效的文件方式,所以它被用于加载动态库。创建一个不对应于任何文件的匿名内存映射也是可能的,此方法用于存放程序的数据。在中,如果你通}

我要回帖

更多关于 玩游戏电脑自动重启 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信