现代体系结构上的UNIX系统 (内核程序员的SMP和Caching技术)

https://www.amazon.com/UNIX-Systems-Modern-Architectures-Multiprocessing/dp/0201633388

https://book.douban.com/subject/1229889/

在同一个进程内从一个线程切换到另一个线程的操作称为线程切换( thread switch)。因为进程不变,所以不需要改变地址空间的映射关系。

系统调用 sbrk和 brk能够让进程改变它的断开地址,从而增长或者缩小 bss段的大小。

全相联高速缓存构建起来要比同等大小、但每组行数较少的高速缓存成本高,因为必须并行搜索高速缓存中的所有行。这就是全相联高速缓存很少用于指令和数据的主要原因。在使用它们的时候,通常是小规模、有特殊用途且有高度时间局部性的高速缓存,比如转换后备缓冲器( translation lookaside buffer, TLB)。 TLB高速缓存最近在 MMU内使用过虚拟地址到物理地址的转换。小规模、全相联的 TLB比较实用,因为大多数程序都体现出了局部引用特性,这意味着工作集的转换会被多次使用。此外,因为每一次转换都映射了完整的一页数据,所以只需几个转换就能提供良好的性能。

将指令高速缓存和数据高速缓存分开的做法目前在计算机系统中相当常见。这种做法能够有效地使高速缓存的带宽加倍,因为它能让 CPU从指令高速缓存预取指令的同时把数据载入或者保存到数据高速缓存中。图 2-17描绘了这样的一种组织结构。本章提到的所有处理器,除了 Intel 80486之外,其片上高速缓存都有独立的指令高速缓存和数据高速缓存。

这种组织结构最重要的方面就是缺乏数据高速缓存和指令高速缓存之间的直接互连。如果在指令高速缓存中没有命中某个指令,那么指令高速缓存就无法到数据高速缓存中查找它。指令高速缓存始终都是从主存储器读取指令来完成缺失操作。类似地,数据高速缓存中的缺失也要从主存储器读取。把数据保存到数据高速缓存中不会影响指令高速缓存的内容。虽然这是一种最简单的实现,但是它可能会产生高速缓存的不一致性,因为主存储器的内容可能会被缓存在一个以上的地方。如果使用单一的、将指令和数据结合在一起的高速缓存,就不会出现这类不一致性。(见与JIT这样的情况)

虚拟高速缓存是操作系统最难以管理的高速缓存类型,尽管它通过省略地址转换步骤能够加快向 CPU返回数据的速度。所有问题围绕着用虚拟地址来检索和标记高速缓存行这一事实而出现。虚拟地址不能唯一地确定一段数据,因为多个进程可以使用相同范围的虚拟地址。除非操作系统能够采取步骤来防止出现这种情况,否则高速缓存中就会出现歧义( ambiguity)和别名( alias)现象。

别名也叫做同义( synonym),当使用一个以上虚拟地址来指代相同的物理地址时就发生了别名现象(多个虚拟地址被称为别名)。如果一个进程将同一共享存储区附加在它的地址空间中两个不同的虚拟地址上,或者两个不同的进程在它们各自地址空间的不同地址上使用同一共享存储区,就会发生别名现象。如果每个地址经散列算法计算出不同的行索引,那么相同的数据就会被保存在高速缓存中不同的地方。如果两个版本的数据彼此失去同步,就会发生意想不到的结果。

正如以后的章节中将会看到的那样,通过改变高速缓存的组织结构,以某种方式使用物理地址,就有可能避免让操作系统显式地冲洗高速缓存。例如, Intel i860 XP上的高速缓存在标记中除了包括虚拟地址之外,还包括物理地址。这就让硬件能够检测到一些情况下的别名和歧义(这种组织结构将在 6. 2. 6节中介绍)。但是,这里的讨论集中在纯虚拟高速缓存上,即那些仅使用虚拟地址的高速缓存。

每次上下文切换的时候冲洗虚拟高速缓存可能是一项耗时的操作,尤其是当采用了大规模的写回高速缓存时更是如此。冲洗高速缓存所需的时间不仅跟高速缓存的大小成比例,而且也跟高速缓存的行数成比例,因为所有修改过的行都被写回到主存储器中。

动态地址绑定的一个缺点是它从程序的执行环境中删除了一个确定性的元素,即固定的区域起始地址。没有了这个确定性的元素,将意味着一个程序必须经受更广泛的测试,以确保它对加载它的虚拟地址没有隐藏的依赖性。第二,这些技术只能在具有大规模高速缓存的系统上才能产生可度量的性能增益。较小的高速缓存在任何情况下都不能保存大量进程的局部引用信息,所以计算一个能减少高速缓存行争用的载入地址所带来的额外开销并不一定划算。最后,不是所有的体系结构都能高效地支持位置无关的代码。因此,跟那些位置有关的代码相比,性能可能还有些降低,所以必须把它和高速缓存性能上可能的提升相对照来进行衡量。

在 SMP系统中可以投入实际工作的最大 CPU数目受到共享总线和存储器的带宽限制。这个带宽在设计系统的时候就固定下来了,它必须足以满足系统中所有 CPU和 I/ O设备的需要,否则系统的整体性能就会受损。例如,如果总线和主存储器的带宽为 20 Mbit/ s,而 I/ O设备需要在一个给定的应用环境中执行 5 Mbit/ s的 DMA传输,那么这就给 CPU剩下了 15 Mbit/ s的可用带宽。如果每个 CPU要连续执行指令而没有延迟,需要 3 Mbit/ s的带宽,那么系统就最多支持 5个 CPU。