Man*_*lva 16 hardware multithreading operating-system multicore mmu
在单核计算机上,一次执行一个线程.在每个上下文切换上,调度程序检查要调度的新线程是否与前一个线程处于同一进程中.如果是这样,则不需要对MMU(页面表)进行任何操作.在另一种情况下,需要使用新的流程页表更新页表.
我想知道多核计算机上是怎么发生的.我猜每个核心上都有一个专用的MMU,如果同一进程的两个线程同时在2个核心上运行,则每个核心的MMU只需引用相同的页面表.这是真的 ?你能指点我对这个问题的好的参考吗?
例如,在ARM上,顶层(Linux中使用的PGD或页面全局目录名称)覆盖1MB的地址空间。在简单的系统中,您可以映射为1MB的部分。但是,这通常指向第二级表(PTE或页面表条目)。
有效实现多CPU的一种方法是每个CPU 具有单独的顶层PGD。内核之间的操作系统代码和数据将保持一致。每个内核都有自己的TLB和L1缓存;L2 / L3缓存可以共享也可以不共享。数据/代码缓存的维护取决于它们是VIVT还是VIPT,但这是一个附带问题,不应影响MMU和多核的使用。
该过程的第二级页表的或用户部分保持每同一过程 ; 否则,它们将具有不同的内存,或者您需要同步冗余表。当各个内核运行不同的进程时,它们可能具有不同的第二级页面表集(不同的顶级页面表指针)。如果它是多线程的,并且在两个CPU上运行,则顶级表可能包含该进程相同的第二级页面表条目。实际上,当两个CPU运行相同的进程时,整个顶层页面表可能相同(但内存不同)。如果线程本地数据是通过MMU实现的,则单个条目可能会有所不同。但是,由于TLB和缓存问题(刷新/一致性),线程本地数据通常以其他方式实现。
下图可能会有所帮助。图中的CPU,PGD和PTE条目有点像指针。
的虚线是运行不同的过程和相同的处理(多线程的情况下)与所述MMU之间的唯一区别; 它是从CPU2 PGD到进程B PTE或第二级页表的实线的替代。内核始终是多线程CPU应用程序。
转换虚拟地址时,不同的位部分是每个表的索引。如果虚拟地址不在TLB中,则CPU必须进行表遍历(并获取其他表内存)。因此,一次读取过程内存将导致三个内存访问(如果不存在TLB)。
内核代码/数据的访问权限明显不同。实际上,可能还会存在其他问题,例如设备内存等。但是,我认为该图应该使MMU如何保持多线程内存相同是显而易见的。
每个线程在第二级表中的条目完全可能不同。但是,这将在同一个CPU上切换线程时产生成本,因此通常会映射所有“线程本地”的数据,并使用其他选择数据的方法。通常,线程本地数据是通过指针或索引寄存器(每个CPU专用)找到的,该指针或索引寄存器被映射/指向“进程”或用户内存中的数据。“线程本地数据”不是与其他线程隔离的,因此,如果一个线程中的内存被覆盖,则可能会杀死另一个线程的数据。