Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 在循环中插入nop和在movnti存储区附近读取导致意外减速 我无法理解为什么第一个代码每次迭代有~1个周期,而第二个代码每次迭代有2个周期。我用Agner的工具和性能测量。根据IACA,从我的理论计算来看,它应该需要1个周期_Performance_Optimization_X86_Micro Optimization - Fatal编程技术网

Performance 在循环中插入nop和在movnti存储区附近读取导致意外减速 我无法理解为什么第一个代码每次迭代有~1个周期,而第二个代码每次迭代有2个周期。我用Agner的工具和性能测量。根据IACA,从我的理论计算来看,它应该需要1个周期

Performance 在循环中插入nop和在movnti存储区附近读取导致意外减速 我无法理解为什么第一个代码每次迭代有~1个周期,而第二个代码每次迭代有2个周期。我用Agner的工具和性能测量。根据IACA,从我的理论计算来看,它应该需要1个周期,performance,optimization,x86,micro-optimization,Performance,Optimization,X86,Micro Optimization,每次迭代需要1个周期。 ; array is array defined in section data %define n 1000000 xor rcx, rcx .begin: movnti [array], eax add rcx, 1 cmp rcx, n jle .begin 每次迭代需要2个周期。但为什么 ; array is array defined in section data %define n 1000000 xor rcx

每次迭代需要1个周期。

; array is array defined in section data
%define n 1000000
xor rcx, rcx   

.begin:
    movnti [array], eax
    add rcx, 1 
    cmp rcx, n
    jle .begin

每次迭代需要2个周期。但为什么

; array is array defined in section data
%define n 1000000
xor rcx, rcx   

.begin:
    movnti [array], eax
    nop
    add rcx, 1 
    cmp rcx, n
    jle .begin

这个最终版本每次迭代大约需要27个周期。但是为什么呢?毕竟,没有依赖链

.begin:
    movnti [array], eax
    mov rbx, [array+16]
    add rcx, 1 
    cmp rcx, n
    jle .begin

我的CPU是IvyBridge。

movnti
是2个uops,不能微熔合,根据IvyBridge的说法

因此,您的第一个循环是4个融合域UOP,并且可以在每个时钟的一次迭代中发出

nop
是第五个融合域uop(即使它不接受任何执行端口,所以它是0个未融合域uop)。这意味着前端只能以每2个时钟发出一个循环

有关CPU工作方式的更多链接,请参见TagWiki



第三个循环可能很慢,因为
mov rbx、[array+16]
可能是从
moventi
退出的同一缓存线加载的。每次刷新它存储到的填充缓冲区时都会发生这种情况。(不是每个
movnti
,显然它可以在同一个填充缓冲区中重写某些字节。)

如果您打算很快读取它,请避免非临时存储。非时态存储的全部要点是只写突发,不会导致行被“写分配”(读)到缓存中。指令的使用告诉CPU“不要把它放在缓存中,只要把它写到内存中,我保证不会很快使用它”来自同一个用户的相关问题。什么是填充缓冲区?是的,当
mov-rbx、[array+64]
代替
mov-rbx、[array+16]
时,循环再次变快。缓存线只有64个字节。@J.Doe。查看我对您的另一个
movinti
问题的回答;我包括了一个链接,指向一篇英特尔文章,该文章讨论了写组合填充缓冲区。是的,我看到了:)谢谢