提交 aed604f8 编写于 作者: W wizardforcel

typo

上级 0e0bdfbc
...@@ -20,11 +20,11 @@ ...@@ -20,11 +20,11 @@
+ 指令寄存器(IR),它含有当前执行的指令的机器码。 + 指令寄存器(IR),它含有当前执行的指令的机器码。
+ 栈指针(SP),它含有当前函数栈帧的指针,其中包含函数参数和局部变量。 + 栈指针(SP),它含有当前函数栈帧的指针,其中包含函数参数和局部变量。
+ 程序当前使用的存放数据的通用寄存器。 + 程序当前使用的存放数据的通用寄存器。
+ 状态寄存器,或者位寄存器,含有当前计算的信息。例如,位寄存器通常含有位来存储上个操作是否是零的结果。 + 状态寄存器,或者位寄存器,含有当前计算的信息。例如,位寄存器通常含有位来存储上个操作是否是零的结果。
在程序运行之中,CPU执行下列步骤,叫做“指令周期”: 在程序运行之中,CPU执行下列步骤,叫做“指令周期”:
+ 取指(Fetch):从内存中取下一条指令,储存在指令寄存器中。 + 取指(Fetch):从内存中取下一条指令,储存在指令寄存器中。
+ 译码(Decode):CPU的一部分叫做“控制单元”,将指令译码,并向CPU的其它部分发送信号。 + 译码(Decode):CPU的一部分叫做“控制单元”,将指令译码,并向CPU的其它部分发送信号。
+ 执行(Execute):收到来自控制单元的信号后会执行合适的计算。 + 执行(Execute):收到来自控制单元的信号后会执行合适的计算。
...@@ -73,13 +73,13 @@ Th + m * Tp ...@@ -73,13 +73,13 @@ Th + m * Tp
另一方面,如果程序不可预测地跳来跳去,从内存中零散的位置读取数据,很少两次访问到相同的位置,缓存的性能就会很低。 另一方面,如果程序不可预测地跳来跳去,从内存中零散的位置读取数据,很少两次访问到相同的位置,缓存的性能就会很低。
程序使用相同数据多于一次的倾向叫做“时间局部性”。使用相邻位置的数据的倾向叫做“空间局部性”。运的是,许多程序天生就带有这两种局部性: 程序使用相同数据多于一次的倾向叫做“时间局部性”。使用相邻位置的数据的倾向叫做“空间局部性”。运的是,许多程序天生就带有这两种局部性:
+ 许多程序含有非跳转或分支的代码块。由于这些代码块,指令顺序指令,访问模式具有空间局部性。 + 许多程序含有非跳转或分支的代码块。在这些代码块中指令顺序执行,访问模式具有空间局部性。
+ 在循环中,程序执行多次相同指令,所以访问模式具有时间局部性。 + 在循环中,程序执行多次相同指令,所以访问模式具有时间局部性。
+ 一条指令的结果通常用于下一指令的操作数,所以数据访问模式具有时间局部性。 + 一条指令的结果通常用于下一指令的操作数,所以数据访问模式具有时间局部性。
+ 当程序执行某个函数时,它的参数和局部变量在栈上储存在一起。这些值的访问具有空间局部性。 + 当程序执行某个函数时,它的参数和局部变量在栈上储存在一起。这些值的访问具有空间局部性。
+ 最普遍的处理模型之一就是顺序读写数元素。这一模式也具有空间局部性。 + 最普遍的处理模型之一就是顺序读写数元素。这一模式也具有空间局部性。
下一节中我们会探索程序的访问模式和缓存性能的关系。 下一节中我们会探索程序的访问模式和缓存性能的关系。
...@@ -159,12 +159,12 @@ Size: 4096 Stride: 64 read+write: 0.7058 ns ...@@ -159,12 +159,12 @@ Size: 4096 Stride: 64 read+write: 0.7058 ns
花一分钟来考虑这张图片,并且看看你是否能推断出缓存信息。下面是一些需要思考的事情: 花一分钟来考虑这张图片,并且看看你是否能推断出缓存信息。下面是一些需要思考的事情:
+ 程序多次遍历并读取数组,所以有大量的时间局部性。如果整个数组能放进缓存,平均缺失惩罚应几乎为0。 + 程序多次遍历并读取数组,所以有大量的时间局部性。如果整个数组能放进缓存,平均缺失惩罚应几乎为0。
+ 当步长是4的时候,我们读取了数组的每个元素,所以程序有大量的空间局部性。如果块大小足以包含64个元素,例如,即使数组不能完全放在缓存中,命中率应为63/64。 + 当步长是4的时候,我们读取了数组的每个元素,所以程序有大量的空间局部性。例如,如果块大小足以包含64个元素,即使数组不能完全放在缓存中,命中率应为63/64。
+ 如果步长等于块的大小(或更大),空间局部性应为0,因为每次我们读取一个块的时候,我们只访问一个元素。这种情况下,我们会看到最大的缺失惩罚。 + 如果步长等于块的大小(或更大),空间局部性应为0,因为每次我们读取一个块的时候,我们只访问一个元素。这种情况下,我们会看到最大的缺失惩罚。
总之,如果数组比缓存大小更小,或步长小于块的大小,我们认为会有良好的缓存性能。如果数组大于缓存大小,并且步长较大时,性能只会下降。 总之,如果数组比缓存大小更小,或步长小于块的大小,我们认为会有良好的缓存性能。如果数组大于缓存大小,并且步长较大时,性能只会下降。
在图7.1中,缓存性能对于所有步长很好,只要数组小于`2 ** 22`字节。我们可以推测缓存大小近似4MiB。实际上,根据规范应该是3MiB。 在图7.1中,只要数组小于`2 ** 22`字节,缓存性能对于所有步长都很好。我们可以推测缓存大小近似4MiB。实际上,根据规范应该是3MiB。
当步长为8、16或32B时,缓存性能良好。在64B时开始下降,对于更大的步长,平均缺失惩罚约为9ns。我们可以推断出块大小为128B。 当步长为8、16或32B时,缓存性能良好。在64B时开始下降,对于更大的步长,平均缺失惩罚约为9ns。我们可以推断出块大小为128B。
...@@ -188,11 +188,11 @@ Size: 4096 Stride: 64 read+write: 0.7058 ns ...@@ -188,11 +188,11 @@ Size: 4096 Stride: 64 read+write: 0.7058 ns
在这一章的几个位置上,你可能会有一个问题:“如果缓存比主存快得多,那为什么不使用一大块缓存,然后把主存扔掉呢?” 在这一章的几个位置上,你可能会有一个问题:“如果缓存比主存快得多,那为什么不使用一大块缓存,然后把主存扔掉呢?”
在没有深入计算机体系结构之前,可以给出两个原因:电子和经济学上的。缓存很快是由于它们很,并且离CPU很近,这可以减少由于电容造成的延迟和信号传播。如果你把缓存做得很大,它就变得很慢。 在没有深入计算机体系结构之前,可以给出两个原因:电子和经济学上的。缓存很快是由于它们很,并且离CPU很近,这可以减少由于电容造成的延迟和信号传播。如果你把缓存做得很大,它就变得很慢。
另外,缓存占据处理器芯片的空间,更大的处理器会更贵。主存通常使用动态随机访问内存(DRAM),每位上只有一个晶体管和一个电容,所以它可以将更多内存打包在同一空间上。但是这种实现内存的方要比缓存实现的方式更慢。 另外,缓存占据处理器芯片的空间,更大的处理器会更贵。主存通常使用动态随机访问内存(DRAM),每位上只有一个晶体管和一个电容,所以它可以将更多内存打包在同一空间上。但是这种实现内存的方要比缓存实现的方式更慢。
同时主存通常包装在双列直插式内存模块(DIMM)中,它包含至少16个芯片。几个小型芯片比一个大型芯片更便宜。 同时主存通常包装在双列直插式内存模块(DIMM)中,它至少包含16个芯片。几个小型芯片比一个大型芯片更便宜。
速度、大小和成本之间的权衡是缓存的根本原因。如果有既快又大还便宜的内存技术,我们就不需要其它东西了。 速度、大小和成本之间的权衡是缓存的根本原因。如果有既快又大还便宜的内存技术,我们就不需要其它东西了。
...@@ -229,7 +229,7 @@ Size: 4096 Stride: 64 read+write: 0.7058 ns ...@@ -229,7 +229,7 @@ Size: 4096 Stride: 64 read+write: 0.7058 ns
这些问题的答案构成了“缓存策略”。在靠近顶端的位置,缓存策略倾向于更简单,因为它们非常快,并由硬件实现。在靠近底端的位置,会有更多做决定的次数,并且设计良好的策略会有很大不同。 这些问题的答案构成了“缓存策略”。在靠近顶端的位置,缓存策略倾向于更简单,因为它们非常快,并由硬件实现。在靠近底端的位置,会有更多做决定的次数,并且设计良好的策略会有很大不同。
多数缓存策略基于历史重演的原则,如果我们有最近时期的信息,我们可以用它来预测不久的将来。例如,如果一块数据在最近使用了,我们认为它不久之后会再次使用。这个原则展示了一种叫做“最近最少使用”,即LRU。它从缓存中移除最久未使用的数据块。更多话题请见[缓存算法的维基百科](http://en.wikipedia.org/wiki/Cache_algorithms) 多数缓存策略基于历史重演的原则,如果我们有最近时期的信息,我们可以用它来预测不久的将来。例如,如果一块数据在最近使用了,我们认为它不久之后会再次使用。这个原则展示了一种叫做“最近最少使用”的策略,即LRU。它从缓存中移除最久未使用的数据块。更多话题请见[缓存算法的维基百科](http://en.wikipedia.org/wiki/Cache_algorithms)
## 7.8 页面调度 ## 7.8 页面调度
...@@ -250,7 +250,7 @@ Size: 4096 Stride: 64 read+write: 0.7058 ns ...@@ -250,7 +250,7 @@ Size: 4096 Stride: 64 read+write: 0.7058 ns
+ 大多数进程不会用完所分配的内存。`text`段的许多部分都永远不会执行,或者执行一次就再也不用了。这些页面可以被换出而不会引发任何问题。 + 大多数进程不会用完所分配的内存。`text`段的许多部分都永远不会执行,或者执行一次就再也不用了。这些页面可以被换出而不会引发任何问题。
+ 如果程序泄露了内存,它可能会丢掉所分配的空间,并且永远不会使用它了。通过将这些页面换出,操作系统可以有效填补泄露。 + 如果程序泄露了内存,它可能会丢掉所分配的空间,并且永远不会使用它了。通过将这些页面换出,操作系统可以有效填补泄露。
+ 在多数系统中,有些进程像守护进程那样,多数时间下都是限制的,只在特定场合被“唤醒”来响应时间。当它们闲置时,这些进程可以被换出。 + 在多数系统中,有些进程像守护进程那样,多数时间下都是闲置的,只在特定场合被“唤醒”来响应事件。当它们闲置时,这些进程可以被换出。
+ 另外,可能有许多进程运行同一个程序。这些进程可以共享相同的`text`段,避免在物理内存中保留多个副本。 + 另外,可能有许多进程运行同一个程序。这些进程可以共享相同的`text`段,避免在物理内存中保留多个副本。
如果你增加分配给所有进程的总内存,它可以超出物理内存的大小,并且系统仍旧运行良好。 如果你增加分配给所有进程的总内存,它可以超出物理内存的大小,并且系统仍旧运行良好。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册