6 c malloc caching virtual-memory
我试图理解为什么可以以某种方式编写使用数组(例如矩阵乘法)的程序来利用缓存的空间局部性。
缓存提供的空间局部性是指虚拟内存、物理内存或两者中的局部性吗?当计算机系统将一块数据从主内存带入 CPU 缓存时,它是否将虚拟或物理上连续的数据对象带入 CPU 缓存?
当我们以非动态方式或动态方式(通过 malloc())定义一个数组或结构对象时,连续分配这样的数组或对象是否正确?“连续”是指虚拟内存还是物理内存或两者兼而有之?
如果缓存的空间局部性是用于物理内存而不是虚拟内存,并且操作系统可以分配给 C 程序实际上不一定是物理连续的数组,那么我们如何编写程序来利用缓存的空间局部性?
谢谢。
1)确实两者都有,但原因很微妙。
\n\n2) 高速缓存对称为行的数据块进行操作,行内的字节在虚拟和物理上都是连续的。典型的行大小为 16、32、64 字节。\n如果两个相邻的缓存行位于同一页内,则它们必须在物理上连续。典型的页面大小为 4、8、16 K。因此,具有 32 字节高速缓存行和 4K 基本页的机器每页有 128 行。
\n\n3,4) 在 C 中,结构、联合或数组的成员实际上是连续的。物理上是否连续取决于操作系统。
\n\n(1) 第 2 部分:还有另一个缓存,称为转换后备缓冲区 (TLB),它保留最近使用的页面映射。如果没有这样的机制,每个内存引用都需要两个物理内存引用:一个用于加载内存地址转换,然后应用该内存地址转换来生成所需的内存引用。
\n\n假设你的 TLB 有 32 个条目(现在小得愚蠢),并且你有这样的代码来遍历数组:
\n\nchar *p;\nfor (p = array; p < array + 4096; p++) {\n char *q;\n for (q = p; q < p + 32 * 4096; q += 4096) {\n *q += 1;\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n您可以有效地模拟没有 TLB 的机器,因为 \xe2\x80\x98*q\xe2\x80\x99 的每个内存引用都会在 TLB 中丢失,并且需要从内存中获取。
\n\n如果您了解缓存关联性和大小的详细信息,则可以为内存缓存构建类似的病态情况;或者如果你不幸的话,你可能会不小心碰到它并想知道为什么你的程序这么慢。
\n