英特尔酷睿i7处理器和缓存行为

时间:2017-03-28 15:50:42

标签: c performance caching assembly intel

我在Intel Core i7 CPU(具有32KB L1数据缓存和64B L1缓存行大小)上运行以下汇编代码:(通过一个包含4个字节的10 000 000个元素的数组迭代1000次)

main:
.LFB0:
    .cfi_startproc
    mov edx, 1000
    jmp .L2
.L3:
    mov ecx, DWORD PTR v[0+eax*4]
    add eax, 1

    cmp eax, 10000000
    jl  .L3
    sub edx, 1
    je  .L4
.L2:
    mov eax, 0
    jmp .L3
.L4:
    mov eax, 0
    ret
    .cfi_endproc

Perf给出以下统计数据:

10,135,716,950      L1-dcache-loads
601,544,266      L1-dcache-load-misses     #    5.93% of all L1-dcache hits
4.747253821 seconds time elapsed

这很有意义,因为我在内存中访问1 000 * 10 000 000 = 10 000 000 000个元素,并且缓存行为64B(向量为4 B的元素)这意味着每次都有L1缓存未命中16个元素(因此大约625 000 000个L1缓存未命中)。

现在,我已经"展开"循环的一部分,代码是:

    .cfi_startproc
    mov     edx, 1000
    jmp     .L2
.L3:
    mov     ecx, DWORD PTR v[0+eax*4]
    mov     ecx, DWORD PTR v[0+eax*4 + 4]
    mov     ecx, DWORD PTR v[0+eax*4 + 8]
    mov     ecx, DWORD PTR v[0+eax*4 + 12]

    add     eax, 4

    cmp     eax, 2500000
    jl      .L3
    sub     edx, 1
    je      .L4
.L2:
    mov     eax, 0
    jmp     .L3
.L4:
    mov     eax, 0
    ret
    .cfi_endproc

Perf如何给出以下统计数据:

2,503,436,639      L1-dcache-loads
123,835,666      L1-dcache-load-misses     #    4.95% of all L1-dcache hits
0.629926637 seconds time elapsed

我不明白为什么?

1)L1缓存负载较少,因为我访问的数据量相同?

2)代码运行速度比第一个版本快6倍?我知道它有 与无序执行和超标量执行有关,但我无法详细解释这一点(我想了解导致这种加速的原因)。

1 个答案:

答案 0 :(得分:4)

坏消息 - 你的第二个错误;)

原始代码

.L3:
    mov ecx, DWORD PTR v[0+eax*4]
    add eax, 1
    cmp eax, 10000000
    jl  .L3

第二版

.L3:
    mov     ecx, DWORD PTR v[0+eax*4]
    mov     ecx, DWORD PTR v[0+eax*4 + 4]
    mov     ecx, DWORD PTR v[0+eax*4 + 8]
    mov     ecx, DWORD PTR v[0+eax*4 + 12]
    add     eax, 4
    cmp     eax, 2500000  <- here
    jl      .L3

在这两种情况下,您需要加载10万个元素。在两种情况下访问的最大元素地址必须相同,对吧?

所以在第一种情况下,max address是:

(10.000.000-1)*4 = 39.999.996

和第二:

(2.500.000-4)*4+12 = 9.999.996

正好少了4倍。

只需将第二个示例修改为cmp eax, 10000000