我正在阅读操作系统概念,我在第8章!但是,我可以使用一些澄清,或者保证我的理解是正确的.
逻辑地址:根据本书,CPU生成逻辑地址.这到底是什么意思?(在执行生成的地址系统中..)我假设在为程序编译代码时,程序不知道代码将在何处加载到内存中.所有编译器都会设置程序布局的一般草图以及图像的布局方式,但不会为其分配任何实际地址.当程序执行时,CPU获取编译器生成的这个布局图像,并将一些地址(逻辑1)分发给从代码生成的地址.
物理地址:直到CPU生成一组逻辑地址(由基地址和偏移量组成)之后才生成物理地址.逻辑地址通过MMU或其他设备,沿着线路的某处,逻辑地址映射到物理RAM地址.
那么实际差异是什么?我可以看到一个好处.使用逻辑地址为应用程序提供了更多自由.如果物理地址是硬编码的,那么程序的成功将在很大程度上取决于物理计算机,可用的RAM地址等.
转换为物理地址的逻辑地址的使用是否会产生两个步骤而不是一对一,因此更多地超过?
然后逻辑地址在生成后驻留在哪里?它们可能存在于CPU上的寄存器中,而CPU正在为一个进程提供服务,但在它之前和之后,它们去哪里了?我理解这是依赖于实现的.我假设它们可能存储在CPU的某些特殊寄存器空间或缓冲区中,例如TLB,对吗?如果没有,那么表可能存在于实际的RAM本身中,而CPU只保存一个指针/地址到RAM中表的基地址,对吗?
看起来保持RAM中的地址对逻辑存储器地址的目的是有效的.我只能假设我的理解不正确.
请考虑以下情况:内核耗尽了物理RAM并需要换出页面.它选择最近最少使用的页面框架,并希望将其内容交换到磁盘并将该框架分配给另一个进程.
困扰我的是,这个页面框架已经映射到一般来说,几个(相同的)几个进程的页面.内核必须以某种方式找到所有这些进程并将页面标记为已换出.它是如何实现的?
谢谢.
编辑:问题的插图:
在交换过程1和2之前有一个共享的Page 1,它位于物理内存帧1中:

现在,系统中的内存耗尽,内核通过从第1帧交换第1页并将其替换为第2页来为进程3分配内存.为了做到这一点,它必须
1)找到所有流程,参考第1页(在我们的案例中为流程1和流程2)
2)修改其页表条目,将"Present"位设置为0并在Swap中设置Page 1位置

所以,我不知道,第1步是如何进行的.内核不能只是迭代地查看每个进程的页表,以便找到指向第1帧的页表条目.应该存在从页框到页表条目的某种反向映射.
答案是:
"页表管理最重要和最重要的变化是引入了反向映射(rmap).将其称为"rmap"是故意的,因为它是"首字母缩略词"的常见用法,不应与-rmap混淆由Rik van Riel开发的树,它对库存VM的更多改动而不仅仅是反向映射.
在一个句子中,rmap授予定位所有PTE的能力,这些PTE仅在给定结构页面的情况下映射特定页面.在2.4中,找到映射共享页面的所有PTE(例如内存映射共享库)的唯一方法是线性搜索属于所有进程的所有页表.这太昂贵了,Linux试图通过使用交换缓存来避免这个问题(参见11.4节).这意味着对于许多共享页面,无论页面使用时间和使用模式如何,Linux都可能必须更换整个进程.2.6而是有一个与每个结构页面相关联的PTE链,可以遍历该页面以从引用它的所有页面表中删除页面.这样,LRU中的页面可以以智能方式交换出来,而无需交换整个过程."
从了解Linux内存管理,"Linux2.6中的新功能"
我试图使用pmap -x命令在Linux x86-64上查看进程的内存映射.看着pmap的输出我很困惑.特别是对于映射动态库的条目.它们有多个条目(实际上它们全部为4个,其中一些条目有3个条目).以下是一个例子
Address Kbytes RSS Dirty Mode Mapping
00000036ca200000 88 64 0 r-x-- libpthread-2.5.so
00000036ca216000 2044 0 0 ----- libpthread-2.5.so
00000036ca415000 4 4 4 r---- libpthread-2.5.so
00000036ca416000 4 4 4 rw--- libpthread-2.5.so
Run Code Online (Sandbox Code Playgroud)
每个库的第二行总是大小为2MB,而没有页面权限.在所有图书馆中,似乎它的RSS始终为零.最后两行也具有相同的大小(基页大小)和相同的权限(少数库没有rw映射).
有人对此有一些解释吗?我有点意识到,带有只读保护的映射可能由加载器完成,以读取库的元数据,而具有可执行权限的部分实际上是库的代码.我可能错了.
但我对这一中间行没有任何线索.没有许可,没有用法?谁在这里有一些智慧的话?
我还看到有几页报告在匿名内存上,没有任何模式位设置.这些代表什么?
看来(从查看Linux内核源代码),Swap:度量标准/proc/pid/smaps是给定pid可访问的总交换.
在涉及共享内存的情况下,这似乎是实际交换使用的过度近似.例如,当将父pid与其分叉子节点的交换使用相加时,如果它们在交换中具有共同的共享内存,则看起来该部分(交换的共享内存)被计数多次(每个pid一次).
我的问题是,是否有办法根据共享它的进程数量(类似于Pss:)计算出公平交换使用指标.
在单核计算机上,一次执行一个线程.在每个上下文切换上,调度程序检查要调度的新线程是否与前一个线程处于同一进程中.如果是这样,则不需要对MMU(页面表)进行任何操作.在另一种情况下,需要使用新的流程页表更新页表.
我想知道多核计算机上是怎么发生的.我猜每个核心上都有一个专用的MMU,如果同一进程的两个线程同时在2个核心上运行,则每个核心的MMU只需引用相同的页面表.这是真的 ?你能指点我对这个问题的好的参考吗?
我对Linux内核中的页表管理感到困惑吗?
在Linux内核空间中,在打开页表之前.内核将使用1-1映射机制在虚拟内存中运行.打开页表后,内核会查询页表以将虚拟地址转换为物理内存地址.问题是:
这时,在打开页表后,内核空间仍然是1GB(从0xC0000000 - 0xFFFFFFFF)?
在内核进程的页表中,只映射了0xC0000000 - 0xFFFFFFFF范围内的页表项(PTE)?PTE超出此范围将不会映射,因为内核代码永远不会跳转到那里?
打开页面表之前和之后的映射地址是一样的吗?
例如.在打开页表之前,虚拟地址0xC00000FF映射到物理地址0x000000FF,然后在打开页表后,上面的映射不会改变.虚拟地址0xC00000FF仍然映射到物理地址0x000000FF.不同的是,只有在打开页表后,CPU才会查询页表,将虚拟地址转换为以前无需做的物理地址.
内核空间中的页表是全局的,并且将在系统中的所有进程(包括用户进程)之间共享?
这个机制在x86 32bit和ARM中是一样的吗?
通常,列表既可以作为链接列表实现,也可以作为数组列表实现,这些列表在插入元素时很慢.
我想知道是否可以使用处理器的MMU更有效地实现列表,通过重新映射而不是在插入或删除元素时复制内存.这意味着数组中任何位置的索引和插入/删除都具有O(1)的速度,优于任何其他列表实现.
我的问题是:
Linux on x86-64是否支持多个巨大的页面大小(例如,超过4KB基页大小的2MB和1GB页面大小)?如果是,是否有办法为给定的分配指定使用哪个巨大的页面大小?换句话说,我的问题是,如果使用"MAP_HUGETLB"标志mmap(),它将它们分配映射到默认大小的大页面.无论如何要求将分配映射到非默认的巨页大小?
在"低级编程:英特尔®64架构上的C,汇编和程序执行"一书中,我读到:
每个虚拟64位地址(例如,我们在程序中使用的地址)由几个字段组成.地址本身实际上只有48位宽; 它被符号扩展为64位规范地址.它的特点是它的17个左位是相等的.如果不满足条件,则在使用时立即拒绝该地址.然后借助特殊表将48位虚拟地址转换为52位物理地址.
为什么虚拟地址和物理地址之间的差异为4位?
assembly memory-management virtual-memory memory-address mmu
我想估计由于运行Linux的x86-64(Intel Nehalem)机器上的TLB未命中而导致的性能开销.我希望通过使用一些性能计数器得到这个估计.有没有人对什么是估计这个的最佳方法有一些指示?
谢谢Arka