首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 金山面试:虚函数的效率问题 [已结帖,结帖人:wjb_yd]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • wjb_yd
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 结帖率:
    发表于:2008-10-31 12:06:13 楼主
    今天参加金山二面,面试官问道为什么虚函数效率低

    我答的比较浅,被bs

    后来请教面试官,他说跟cpu流水线执行效率有关,哪位朋友帮忙解释一下,到底是怎么回事,为什么涉及到了流水线?
    100  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • jillnicky
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:10:511楼 得分:0
    进来学习
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • dwen20
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:15:032楼 得分:0
    跟流水线执行效率有关?学习了。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • wuyu637
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:15:473楼 得分:0
    直接问他好了。。这么抽象。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • baihacker
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 4

    发表于:2008-10-31 12:16:514楼 得分:0
    因为虚函数需要一次间接的寻址...
    而一般的函数可以在编译时定位到函数的地址,虚函数(动态类型调用)是要根据某个指针定位到函数的地址.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • hqin6
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:22:155楼 得分:0
    引用 4 楼 baihacker 的回复:
    因为虚函数需要一次间接的寻址...
    而一般的函数可以在编译时定位到函数的地址,虚函数(动态类型调用)是要根据某个指针定位到函数的地址.


    说的不错,虚函数有个虚函数表,而且会传一个index索引~!会间接寻址!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • lzr4304061988012
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:24:356楼 得分:0
    我觉得LZ应该说过LS的,这一提到虚函数,基本都会这样回答.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • Leejun527
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:25:457楼 得分:0
    学习了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • dwen20
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:27:578楼 得分:0
    那何必要跟流水线效率相关呢,一般人很少知道流水线是怎么处理直接和间接寻址的。
    间接寻址通常比直接寻址要慢是肯定的嘛。这面试官够狠。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • baihacker
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 4

    发表于:2008-10-31 12:29:219楼 得分:0
    流水线执行的话,和"命中率"有关吧.
    也就是说在流水线后端,已经译码成功的,和正在执行的代码的后继是一样的.

    否则流水线会中断,也就是说在后端做的是无效的,需要重新译码.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • baihacker
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 4

    发表于:2008-10-31 12:33:4610楼 得分:0
    如果是流水线的话.

    准备虚函数表头指针. (可能会有些额外的thunk,在确定一个动态类型对象(我这里是指一个引用或者指针),会和头指针关联(在多重继承下会有这些复杂的情况))
    准备虚函数表里的id. (编译时确定)
    通过访问虚函数表,得到函数地址.(好像是在构造函数的调用时准备好)
    调用函数.

    怎么会中断流水线呢?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • feeboby
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:36:0811楼 得分:0
    可能是因为用虚函数的时候会有JMP (或者其他跳转)指令,导致预取的指令全部被丢弃!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • jackzhhuang
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:36:5312楼 得分:0
    的确,计算机程序效率说到底和计算机指令流水线息息相关(还和缓存命中率有关)。

    但是,把虚函数效率低的原因解释到流水线这一层,是极其变态的,这个考官很可能是在卖弄自己的水平而已。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • jackzhhuang
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:39:4213楼 得分:0
    楼主以后你要是遇到这种考官,你和他谈与非逻辑门,硅锗原子的组成和爱因斯坦相对论对虚函数的影响,绝对震惊四座!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • dwen20
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:40:0514楼 得分:0
    可以到汇编层去看看。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • Demon__Hunter
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:40:2115楼 得分:0
    学习 up~~
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ZW_Ren
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:42:4916楼 得分:0
    说是因为流水线执行的原因,根本与问题不着边际。
    或者应该说影响流水线执行是效率低的无数原因中的一种才好。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • glacier3d
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:42:5417楼 得分:0
    有深度啊,计算机软硬都考了下
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • MilanSpiRiT
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:43:1318楼 得分:0
    面试官的回答好深奥啊,高人快来指点一下~
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • jiannye
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:43:5919楼 得分:0
    引用 4 楼 baihacker 的回复:
    因为虚函数需要一次间接的寻址...
    而一般的函数可以在编译时定位到函数的地址,虚函数(动态类型调用)是要根据某个指针定位到函数的地址.


    HOHO 学习了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zmlovelx
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:45:3320楼 得分:0
    首先是由this指向查找虚函数表,然后找到相应的虚函数地址
    比非虚函数多查找一次
    如果是(多继承)基类指针指向派生类对象的话,有可能会涉及this指针的调整
    比如先访问基类的成员数据再访问派生类的析构函数  就要进行一次this指针的调整
    具体可以参见 insied the c++ object model的多重继承下的virtual functions
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • 悠悠长风
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:45:4621楼 得分:0
    引用 13 楼 jackzhhuang 的回复:
    楼主以后你要是遇到这种考官,你和他谈与非逻辑门,硅锗原子的组成和爱因斯坦相对论对虚函数的影响,绝对震惊四座!


    支持!!!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • iambic
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 4

      4

      4

    发表于:2008-10-31 12:46:0022楼 得分:0
    给面试官以深深的鄙视。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zctom23
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:46:0023楼 得分:0
    mark学习下
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • sky04
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:46:0424楼 得分:0
    靠,扯到流水线水平了,学习了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cftxlin
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:51:0525楼 得分:0
    一些C++的书籍有明确的说明,针对类的虚函数的机制,如果有虚函数的话,编译器会为类增加一个虚函数表(VBL),当在动态执行程序时,会到该虚函数表中寻找函数。多增加了一个过程,效率肯定会低一些,但带来了运行时的多态。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • bhdgx
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:52:0526楼 得分:0
    学习了,虚函数还与流水线有关
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • rgmlkthh
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:52:2327楼 得分:0
    虽然说知其然,更要知其所以然,但这也太远了点吧。这样搞,随便问个编程的问题,都得说到8086去了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • anglecloudy
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:52:2828楼 得分:0
    ME 靠
    第一次想过这个问题
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zmlovelx
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:52:3829楼 得分:0
    扯上流水线了.有点深啊
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • jia_xiaoxin
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-10-31 12:54:0730楼 得分:0
    在调用虚函数之前,还调用了获得虚函数地址的代码。也就是虚函数需要一次间接的寻址

    cpu流水线:
    流水线是Intel首次在486芯片中开始使用的。流水线的工作方式就象工业生产上的装配流水线。在CPU中由5—6个不同功能的电路单元组成一条指令处理流水线,然后将一条X86指令分成5—6步后再由这些电路单元分别执行,这样就能实现在一个CPU时钟周期完成一条指令,因此提高CPU的运算速度。经典奔腾每条整数流水线都分为四级流水,即指令预取、译码、执行、写回结果,浮点流水又分为八级流水。
    修改 删除 举报 引用 回复