zoukankan      html  css  js  c++  java
  • 虚函数的效率问题

    c++ 虚函数机制 效率问题

    1,多一次查虚表过程
    2,虚函数 效率低 是因为 执行过程中会跳转两次(首先找到对象的函数表,其次通过该函数表中存的虚函数表地址找到真正的执行地址),这样CPU运行的时候会跳转两次,而普通函数只跳一次。CPU每跳转一次,预取指令基本上就要作废很多,所以效率会很低。”
    /////////////////////////////////////最后得分者
    和流水线相关是说得通的,究其原因还是因为存在动态跳转,这会导致分支预测失败,流水线排空。

    设想一下,如果说不是虚函数,那么在编译时期,其相对地址是确定的,编译器可以直接生成jmp/invoke指令;
    如果是虚函数,多出来的一次查找vtable所带来的开销,倒是次要的,关键在于,这个函数地址是动态的,譬如
    取到的地址在eax里,则在call eax之后的那些已经被预取进入流水线的所有指令都将失效。流水线越长,一次分支预测失败的代价也就越大。

    pf->test();
    011E146D mov eax,dword ptr [pf]
    011E1470 mov edx,dword ptr [eax]
    011E1472 mov esi,esp
    011E1474 mov ecx,dword ptr [pf]
    011E1477 mov eax,dword ptr [edx]
    011E1479 call eax <------------------------- 分支预测失效
    011E147B cmp esi,esp
    011E147D call @ILT+355(__RTC_CheckEsp) (11E1168h)

    此兄接着回答道“说到流水线,penalty基本上都是因为气泡(也就是分支指令造成预取失效),知道这个以后碰到了就不会再卡壳了。虽然引入流水线(流水线其实是 RISC最初使用的),极大提高了效率,流水线不是越长越好。像P4,几十级流水线,频率虽高,但是性能不好,很大原因就是因为流水线实在臭长。有兴趣可以去看看CPU怎么做分支预测,乱序执行的。”
    //////////////////////////////////
    还是贴上原帖的地址吧 http://topic.csdn.net/u/20081031/12/06d0e218-8aab-4203-850c-9e6b76099c09.html
    由此还引申出一个问题 虚函数在编译器里是怎么工作的

  • 相关阅读:
    MySql数据类型详解
    MySQL日期数据类型、MySQL时间类型使用总结
    sqlcmd
    sqlserver 复制
    Do waiting or suspended tasks tie up a worker thread?
    用GDB 调试Java程序
    X64相关文章
    How do I find what queries were executing in a SQL memory dump?-----stack
    解决Sublime Text 3中文显示乱码(tab中文方块)问题
    GIT 详解
  • 原文地址:https://www.cnblogs.com/xiayong123/p/3717582.html
Copyright © 2011-2022 走看看