gpt4 book ai didi

assembly - 多态的代价

转载 作者:行者123 更新时间:2023-12-04 20:08:27 26 4
gpt4 key购买 nike

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

mov     rcx, qword ptr [x]   
mov rax, qword ptr [rcx]
call qword ptr [rax+8]

以及 Agner Fog 的延迟表:

http://www.agner.org/optimize/instruction_tables.pdf

当我使用 Ivy Bridge CPU 时,我正在查看第 175 页。
  • 前两条 MOV 指令都只占用 2 个(它们都是将内存移动到寄存器)CPU 周期,我是对的吗?我认为对虚拟方法的调用比这慢?
  • 在第 178 页的指令延迟表中,它说这个调用的延迟是 2 个 CPU 周期(我认为?)。什么CALL 'near' 的意思,而不是 CALL 'r'(寄存器)和 CALL 'm'(内存)?
  • 所以根据 Fog 小册子,上面的 ASM 确实需要 6 个 CPU 周期,我没有误解任何东西?

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

    最佳答案

    Am I right in that the first two MOV instructions both only take 2 (they are both move memory to register) CPU cycles? I thought a call to a virtual method was slower than this? In the instruction latency table page 178 it says the latency of this call is 2 CPU cycles (I think?).



    不,只有最小的延迟才需要 2 个 CPU 周期。

    让我们检查一下 Agner 的表格 http://www.agner.org/optimize/instruction_tables.pdf

    Integer instructions.

    Instruction Operands uops fused domain uops unfused domain (p015 p0 p1 p5 p23 p4) Latency Reciprocal throughput Comments

    Inst   Oper        fus p23 p4  Latency Rec.
    MOV r32/64,m32/64 1 1 2 0.5


    要找到时间,当指令产生结果时,您应该使用“延迟”列。每个 mov 的延迟为 2 个周期,并且仅列出最小值(检查“列标题说明”中的文本 - “延迟 - 这是指令在依赖链中生成的延迟。数字是最小值。缓存未命中,未对准,...可能会显着增加时钟计数。”)

    如果您有很多不同的多态调用,它们所需的内存可能不会被缓存。我们知道缓存和内存延迟来自 different reviews ,所有这些都是通过 long chain of dependent MOV s 测量的喜欢 mov eax, [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 上也不会有 2 周期延迟的机会。 (它的操作数是第一个 mov 的结果,所以在第一个 mov 退休之前没有什么可以乱序执行的)。

    在表格中 http://instlatx64.atw.hu/链接自 Agner's Links Ivy 有报告 InstLatX64 for Intel Core i7-3770K, 3700 MHz用 aida_bench64.dll 制作

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



    该表显示了 L1 缓存中命中的实际延迟 ( L ),4 个周期。

    64-ia-32-architectures-optimization-manual.pdf 中的相同数据(L1 为 4c,L2 为 ~12c,L3 为 26-31c)第 46 页“2.2.5.1 加载和存储操作概述”部分,表“2-10 查找顺序和加载延迟”

    So the above ASM does take 6 CPU cycles according to the Fog booklet, I haven't misinterpretted anything?



    在最好的情况下,当第一次加载提前执行时,关键路径上的乱序 = 2 个周期; L1 中的第二个负载命中 = 关键路径上的 4 个周期; call 2 个周期执行; BTB(分支目标预测/间接分支目标)成功,当从调用的单个地址始终跳转到同一目标(或具有周期性模式的少量目标)时,更有可能 - 您将有 8 个周期来确认该分支被正确预测,可能被目标函数的 OoO 执行部分隐藏。

    如果 L1/L2 中有任何负载未命中,则应添加相应的缓存延迟。如果 L3 未命中,则增加 200 个周期。

    如果 BTB 未命中,您将至少有 15 个周期惩罚(检查 Agner's microarchitecture.pdf,第 27 页“英特尔 Sandy Bridge 和 Ivy Brindge 中的 3.7 分支预测;错误预测惩罚”) - 对于缓存的 uops;更多用于 L1i 中的目标。您可以在同一个 microarchitecture.pdf 第 25 页“PM 和 Core2 中的 3.5 分支预测;间接跳转和调用的模式识别”和“BTB 组织 .. 用于间接跳转和间接调用”中阅读有关旧的 BTB。

    非常有用的文档来自 Intel:“Intel® 64 and IA-32 Architectures
    优化引用手册“ 64-ia-32-architectures-optimization-manual.pdf。它既有调整建议,也有关于性能计数器的信息,这将帮助您获得代码的真实延迟和未命中率(查看 B.6.3.2 部分“虚拟表和间接调用”)。

    关于assembly - 多态的代价,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22264940/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com