Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.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
Assembly 多态性成本_Assembly_X86_Cpu_Branch Prediction - Fatal编程技术网

Assembly 多态性成本

Assembly 多态性成本,assembly,x86,cpu,branch-prediction,Assembly,X86,Cpu,Branch Prediction,我正在查看x86-64中的以下虚拟方法调用: mov rcx, qword ptr [x] mov rax, qword ptr [rcx] call qword ptr [rax+8] 还有Agner Fog的延迟表: 当我使用常春藤桥CPU时,我正在看第175页 前两条MOV指令都只需要2个CPU周期(它们都是移动内存来注册)对吗?我以为调用虚拟方法比这慢 在178页的指令延迟表中,它说这个调用的延迟是2个CPU周期(我想是吧?)。与调用'r'(寄存器)和调用

我正在查看x86-64中的以下虚拟方法调用:

mov     rcx, qword ptr [x]   
mov     rax, qword ptr [rcx]
call    qword ptr [rax+8]
还有Agner Fog的延迟表:

当我使用常春藤桥CPU时,我正在看第175页

  • 前两条MOV指令都只需要2个CPU周期(它们都是移动内存来注册)对吗?我以为调用虚拟方法比这慢

  • 在178页的指令延迟表中,它说这个调用的延迟是2个CPU周期(我想是吧?)。与
    调用
    'r'(寄存器)和
    调用
    'm'(内存)相比,
    调用
    'near'意味着什么

  • 根据Fog手册,上面的ASM需要6个CPU周期,我没有误解任何东西吗

  • 编辑:我将虚拟函数调用更改为vtable中的第二个

    前两条MOV指令都只需要2个CPU周期(它们都是移动内存来注册)对吗?我以为调用虚拟方法比这慢? 在178页的指令延迟表中,它说这个调用的延迟是2个CPU周期(我想是吧?)

    否,仅在最小延迟内有2个CPU周期

    让我们看看阿格纳的桌子

    整数指令

    指令操作数uops融合域uops未融合域(p015 p0 p1 p5 p23 p4)延迟倒数吞吐量注释

    Inst   Oper        fus p23 p4  Latency Rec.
    MOV r32/64,m32/64   1   1        2     0.5
    
    要找到指令产生结果的时间,应该使用“延迟”列。每个mov的延迟为2个周期,并且只列出了最小值(请查看“列标题说明”-“延迟-这是指令在依赖项链中生成的延迟。数字是最小值。缓存未命中、未对齐……可能会显著增加时钟计数。”)

    如果有很多不同的多态调用,那么它们所需的内存可能不会被缓存。我们从中知道缓存和内存延迟,所有这些都是通过like
    moveax[eax]测量的;mov-eax[eax];mov-eax,[eax]。Ivy的值为:L1中的命中=4个周期,L2中的命中=11个周期,L3中的命中=30-40个周期,缓存和访问内存中的未命中=32个周期+60 ns(在3 GHz下,每ns 3个周期>200个周期)。甚至不容易获得2个周期的延迟(什么比L1更接近ALU?对于重新排序的加载,只有72个条目的加载缓冲区?),并且在第二个
    mov
    (它的操作数是第一个mov的结果,所以在第一个mov退役之前,没有什么可以无序执行的)

    在从链接的表格中,有使用aida_bench64.dll制作的常春藤报告

    27 AMD64:MOV r64,[m64]L:1.14ns=4.0c T:0.14ns=0.50c

    此表显示了一级缓存命中的实际延迟(
    L
    ),4个周期

    第46页“2.2.5.1加载和存储操作概述”一节表“2-10查找顺序和加载延迟”中的相同数据(L1为4c,L2为12c,L3为26-31c)

    根据Fog手册,上面的ASM需要6个CPU周期,我没有误解任何东西吗

    在最佳情况下,当第一次加载在关键路径上提前执行且无序=2个周期时;L1中的第二次负载命中=关键路径上的4个循环;
    调用
    执行2个周期;BTB(分支目标预测/间接分支目标)成功,当您总是从单个呼叫地址跳到同一个目标(或跳到少量具有周期模式的目标)时,更可能成功——您将有8个周期来确认分支预测正确,目标函数的OoO执行可能会部分隐藏

    如果一级/二级中有任何加载未命中,则应添加相应的缓存延迟。如果L3未命中,则添加200个循环

    如果BTB未命中,对于缓存的UOP,您将受到至少15次周期惩罚(检查,第27页“英特尔桑迪桥和常春藤布林芝中的3.7分支预测;预测失误惩罚”);更多关于L1i中的目标。您可以在同一微体系结构.pdf第25页“PM和Core2中的3.5分支预测;间接跳转和调用的模式识别”和“间接跳转和间接调用的BTB组织…”中阅读有关旧BTB的内容

    非常有用的文档来自英特尔:“英特尔64和IA-32体系结构”
    优化参考手册”。它包含优化建议和有关性能计数器的信息,这将帮助您获得代码的实际延迟和未命中率(请参阅B.6.3.2“虚拟表和间接调用”一节)。

    不要忘记,任何这些内存访问都可能缓存未命中。而且该调用还可能调用分支目标预测失误。@完全理解。我们只是想看看保证的最低成本。由于移动的唯一依赖性是确认调用目标预测,因此对于正确的预测,操作的延迟将被无序执行隐藏(将有获取、解码和执行开销)。但是,移动的延迟会增加预测失误的惩罚,因为如果调用地址已经在寄存器中,则真实值将在以后可用。@PaulA.Clayton但上述指令都是相互依赖的,因此必须按照该顺序执行?第三个依赖于第二个,第二个依赖于第一个?@user997112:近调用和远调用的不同之处在于目标函数是否在同一内存段中(可怕的东西,坚持x86-64,你不会遇到这种可怕的情况),而寄存器(r)或内存(m)调用的不同程度是间接的。还有相对调用,这些调用可能是最常见的。3或4µOp的块应有效地完全隐藏(而不是“通过OoO执行目标函数部分隐藏”)在Ivy Bridge上,具有>50个问题队列条目和>100个ROB条目-在正确的目标预测下-因为呼叫没有数据依赖性。顺便说一句,OP评论道“只是想看看保证的最低成本。”