2

我在 IvyBridge 上,想测试 L1d 缓存组织。我的理解如下:

在 IvyBridge 上,L1d 缓存有 32K 容量,64B 缓存线,8 路组关联。因此它有 32K/(64*8) = 64 个集合,给定一个主存储器addr,集合索引可以通过 计算(addr/64) % 64

因此,如果我将主内存步进 64*64 (4K),我将始终触摸相同的 L1d 集。一个集合只有 8 个缓存行,因此如果我用 16 个步骤循环它,我将获得几乎 100% 的 L1d 缓存未命中。

我编写了以下程序来验证:

section .bss
align   4096
buf:    resb    1<<26

%define gap 64 * 64 ; no L1 cache miss

; %define gap 64 * 64 * 256 ; 41% L1 cache miss

; %define gap 64 * 64 * 512 ; 95% L1 cache miss
; however, total cycle suggests this gap is already at L3 latency level with complete L2 cache miss.

section .text
global _start
_start:
    mov rcx,    10000000
    xor rax,    rax
loop:
    mov rax,    [buf+rax]
    mov rax,    [buf+rax+gap*1]
    mov rax,    [buf+rax+gap*2]
    mov rax,    [buf+rax+gap*3]
    mov rax,    [buf+rax+gap*4]
    mov rax,    [buf+rax+gap*5]
    mov rax,    [buf+rax+gap*6]
    mov rax,    [buf+rax+gap*7]

    mov rax,    [buf+rax+gap*8]
    mov rax,    [buf+rax+gap*9]
    mov rax,    [buf+rax+gap*10]
    mov rax,    [buf+rax+gap*11]
    mov rax,    [buf+rax+gap*12]
    mov rax,    [buf+rax+gap*13]
    mov rax,    [buf+rax+gap*14]
    mov rax,    [buf+rax+gap*15]

    dec rcx,
    jne loop

    xor rdi,    rdi
    mov rax,    60
    syscall

令我惊讶的是,perf显示根本没有丢失 L1 缓存:

  160,494,057      L1-dcache-loads
        4,290      L1-dcache-load-misses     #    0.00% of all L1-dcache hits

我的理解有什么问题?

4

1 回答 1

3

所有 BSS 页面最初都映射到相同的物理零页面。您将获得 TLB 未命中(可能还有软页面错误),但不会出现 L1d 未命中。

为了避免这种情况并将它们映射到不同的物理页面:

  • 首先通过向每个页面写入一个字节来弄脏它们
  • 也许分配mmap(MAP_POPULATE)而不是使用 BSS。这至少会对它们进行预故障,避免软页面错误,但可能仍然是相同的物理零页面。
  • buf它放在.dataor.rodata部分,它实际上将与文件支持一起映射。(你必须让它更小,因为零实际上会在可执行文件中)。

(对我而言)更有趣的结果是,您确实开始以更大的步幅获得缓存未命中。然后,您将访问更多的总 4k 页面,这可能会导致您的内核开始为您的 BSS 使用 2M 大页面,具有讽刺意味的是,通过使它们不再别名为相同的 4k 物理页面而损害了它。您可以检查/proc/PID/smaps该映射是否存在非零 AnonHuge。


L2 未命中是意料之中的,因为它也只有 8 路关联,但 L3 更具关联性,并使用非简单索引函数将 2 步长的任何简单幂分布到多个集合上。(英特尔酷睿 i7 处理器使用了哪种缓存映射技术?

顺便说一句,您可能需要一个不是 2 的幂的间隙。只是 L1 别名步幅的倍数,而不是 L2 别名步幅的倍数,因此您的数据可以分布在 L2 中的许多集合中。

我一直在寻找重复但没有找到一个确切的,虽然我很确定我之前在 SO >.< 的某个地方已经解释过这个。可能我在想如何在这个循环中获得始终如一的高吞吐量?与malloc而不是BSS完全相同的问题。

有关的:

于 2019-01-07T14:21:00.320 回答