脏位和访问位如何影响 TLB?
我知道如果一个页面已被访问,它将设置访问位,如果已被写入,则脏位也将被设置。但我不清楚这些位如何影响 TLB/TLB 缓存?另外 OSDEV 有以下段落
当某个条目被访问或脏位从 1 更改为 0 时 标记为存在,建议使关联页面失效。 否则,处理器可能不会在后续的操作中设置这些位 由于 TLB 缓存而导致读/写。
在什么情况下您会将脏位和访问位从 1 更改为 0?
I get it that if a page has been accessed it'll have the Access bit set, and if has been written to, the Dirty bit will also be set. But it's unclear to me how these bits affect the TLB/TLB caching? Also OSDEV has the following paragraph
When changing the accessed or dirty bits from 1 to 0 while an entry is
marked as present, it's recommended to invalidate the associated page.
Otherwise, the processor may not set those bits upon subsequent
read/writes due to TLB caching.
In what cases would you change the dirty and access bits from 1 to 0?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果操作系统内存不足,它会想要释放一些页面(例如,将页面的数据发送到交换空间,以便它可以将物理内存用于其他用途)。通常,这将基于“最近最少使用”,但 CPU 每个页面只有 1 个“已访问”标志,因此要解决此问题,操作系统会定期检查已访问标志并将其清除回零,以便它(大致)知道页面被访问了多久,而不仅仅是它是否被访问/未被访问。它有点像“
if(page->accessFlag == 1) { page->accessFlag = 0; page->time_since_access = 0; } else { page->time_since_access++; }
”。对于脏标志,请考虑读/写内存映射文件或回写磁盘缓存。程序修改内存中的数据(导致设置脏标志);然后,当磁盘驱动器无事可做时,操作系统可能会找到设置了脏标志的页面,将它们写入磁盘,并将脏标志清除为零(因此同一页面不会再次写入磁盘)下次就没有理由了)。
恰恰相反 - TLB 影响标志(并且标志不影响 TLB)。
当CPU设置脏或访问标志时,它会对内存进行原子更新以防止竞争条件(例如其他CPU同时修改或检查相同的页表条目),并且原子更新有点昂贵。为了减少/避免这些原子写入,CPU 可以(并且很可能会)将页面的已访问标志和脏标志缓存在 TLB 条目中,以便在 CPU 想要设置标志但 TLB 条目显示时可以跳过原子写入无论如何,它们已经设置好了。如果 TLB 条目错误(例如,因为操作系统更改了内存中的已访问或脏标志,但没有使 TLB 条目无效),则 CPU 可以跳过操作系统所需的原子写入。这可能会导致数据损坏(例如,操作系统假设内存中页面的内容不需要写入磁盘,因为未设置脏标志)。
If the OS is running low on memory it'll want to free some pages (e.g. send the page's data to swap space so it can use the physical memory for something else). Often this will be based on "least recently used", but the CPU only has 1 "accessed" flag for each page, so to work around that the OS checks the accessed flags periodically and clears them back to zero so it knows (roughly) how long ago a page was accessed and not just if it was/wasn't accessed. It's a little like "
if(page->accessFlag == 1) { page->accessFlag = 0; page->time_since_access = 0; } else { page->time_since_access++; }
".For the dirty flag, consider a read/write memory mapped file, or a write-back disk cache. A program modifies data in memory (causing the dirty flag to be set); then when the disk drive has nothing better to do the OS might find pages with the dirty flag set, write them to disk, and clear the dirty flag/s back to zero (so the same page doesn't get written to disk again for no reason next time).
It's more the opposite - the TLB effects the flags (and the flags don't effect the TLB).
When a CPU sets the dirty or accessed flags it does an atomic update of memory to guard against race conditions (e.g. other CPUs modifying or checking the same page table entry at the same time), and atomic updates are somewhat expensive. To reduce/avoid these atomic writes a CPU can (and most likely will) cache the page's accessed and dirty flags in the TLB entry so that the atomic write can be skipped if the CPU wants to set the flag/s but the TLB entry says they're already set anyway. If the TLB entry is wrong (e.g. because the OS changed the accessed or dirty flags in memory but didn't invalidate the TLB entry) then the CPU can skip atomic writes that were needed by the OS. This can cause data corruption (e.g. OS assuming that a page's contents in memory don't need to be written to disk because the dirty flag wasn't set).