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

C++ 虚函数优化探索简介 看了 C++ 的虚函数的一些文章,对于其性能消耗的优化思路整理了一下。 阅读详情
今天在c++坛子里瞎逛,看到精华坛里在讨论“为什么虚函数效率低”的问题,
××楼主回答面试官说“跟cpu流水线执行效率有关”        
××某人回答“因为虚函数需要一次间接的寻址... 而一般的函数可以在编译时定位到函数的地址,虚函数(动态类型调用)是要根据某个指针定位到函数的地址. ” 
×ד虚函数有个虚函数表,而且会传一个index索引~!会间接寻址!”
×ד流水线执行的话,和"命中率"有关吧. 也就是说在流水线后端,已经译码成功的,和正在执行的代码的后继是一样的. 否则流水线会中断,也就是说在后端做的是无效的,需要重新译码.”    
搞笑的是以下人的回复:
×ד的确,计算机程序效率说到底和计算机指令流水线息息相关(还和缓存命中率有关)。但是,把虚函数效率低的原因解释到流水线这一层,是极其变态的,这个考官很可能是在卖弄自己的水平而已。”   
×ד楼主以后你要是遇到这种考官,你和他谈与非逻辑门,硅锗原子的组成和爱因斯坦相对论对虚函数的影响,绝对震惊四座!”
×ד说是因为流水线执行的原因,根本与问题不着边际。或者应该说影响流水线执行是效率低的无数原因中的一种才好。”    
×ד首先是由this指向查找虚函数表,然后找到相应的虚函数地址 
比非虚函数多查找一次 
如果是(多继承)基类指针指向派生类对象的话,有可能会涉及this指针的调整                     
比如先访问基类的成员数据再访问派生类的析构函数  就要进行一次this指针的调整 
具体可以参见 insied the c++ object model的多重继承下的virtual functions ”
×ד一些C++的书籍有明确的说明,针对类的虚函数的机制,如果有虚函数的话,编译器会为类增加一个虚函数表(VBL),当在动态执行程序时,会到该虚函数表中寻找函数。多增加了一个过程,效率肯定会低一些,但带来了运行时的多态。”    
×ד流水线 貌似说的是 CPU执行代码的提前取指令吧 
虚函数 效率低 是因为 执行过程中会跳转两次(首先找到对象的函数表,其次通过该函数表中存的虚函数表地址找到真正的执行地址),这样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.youkuaiyun.com/u/20081031/12/06d0e218-8aab-4203-850c-9e6b76099c09.html
由此还引申出一个问题 虚函数在编译器里是怎么工作的
C++对象的底层原理都在这儿了,还敢说学不会? Part1一、关于对象C 语言是程序性的,语言本身并没有支持数据和函数之间的关联性C++ 中可能采取抽象数据类型,或者是多层次的类结构完成 C++ 的封装并没有增加多少成本,每一个成员函数... 阅读详情

相关推荐

C++之多态

什么是虚函数呢?虚函数就是在基类中被声明为virtual,并在一个或多个派生类中被重新定义的成员函数。是一个成员函数,并且在前面加上virtual关键字如果在基类中定义类虚函数,那么在派生类中该函数就是虚函数,即使在派生类中没有加virtual重定义(重写、覆盖):派生类要保证该虚函数的名字与基类相同,函数的返回类型也要相同,函数的参数列表也要相同(包括参数的个数、参数的类型、参数的顺序),言外之意,唯一可以不一样的,就是函数体。// 类内部class 类名。

weixin_56054625的博客 955

python语句list(range(2、9、2))_Python 语句 list(range(1,10,3)) 执行结果为 ____________________学小易找答案...

【填空题】表达式 len(range(1,10)) 的值是____________【判断题】达碧兹红宝石,是产于缅甸孟速矿区的一种半透明红宝石,内部有6条不移动的星线。 与哥伦比亚达碧兹祖母绿相似而得名【填空题】类型转换函数的原型是 ,类型转换函数的作用是 。【填空题】字典中多个元素之间使用 ______________ 分隔开【填空题】可以使用内置函数 ___________________ 查...

weixin_39802132的博客 1786

利用HFSS仿真优化圆极化微带天线的耦合馈电设计

本文深入探讨了利用HFSS仿真软件优化圆极化微带天线性能的关键方法。通过对比传统直接馈电与耦合馈电方式,详细阐述了耦合馈电在提升阻抗匹配、改善轴比带宽及增强设计鲁棒性方面的显著优势。文章结合FR4板材的实战案例,逐步演示了在HFSS中建立模型、进行参数扫描与圆极化性能优化的完整流程,为设计高性能、高纯度的圆极化天线提供了实用指南。

weixin_29233333的博客 547

c++性能优化-虚函数

虚函数 目录虚函数前言一、虚函数的构造二、模版和继承1.引入库2.读入数据总结 前言 性能优化的目的是为了让程序变得高效,但同时也不能丧失程序的可维护性和可扩展性。 本章总结主要是关于虚函数方面的性能优化的要点 一、虚函数的构造   虚函数想必大家都比较了解。虚函数的引入为c++提供了多态性,为实现面向对象编程奠定了基础。但是仔细分析一下,虚函数的额引入必然也会带来一些开销。比如,虚函数实现的一个重要的指针vptr,正是这个指针使得父类能够正确的找到子类继承的函数;其次,我们必须先得到指向函数表的指针

weixin_34764432的博客 1245

从ST电机库到TI InstaSPIN:手把手对比两种主流FOC实现中的坐标变换差异

本文深入对比了ST电机库与TI InstaSPIN在FOC实现中的坐标变换差异,包括坐标系定义、变换系数和角度处理等关键点。针对BLDC和PMSM电机控制,提供了从理论到实践的移植方案,帮助工程师快速解决平台切换中的性能问题。特别解析了Clarke/Park变换在两种实现中的微妙差异及其对PI控制的影响。

weixin_28724661的博客 398

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(四)-无人机系统(UAS)命令与控制(C2)通信用例

UTM向5G网络提供无人机系统C2通信所需的信息,例如服务类别、无人机系统服务的流量类型、授权的无人机系统服务所需的QoS以及无人机系统服务的订阅。遵循模型B的网络辅助C2模型,为了确保UAS操作的C2通信的服务可用性和可靠性,特别是当无人机在操作员的视线之外(BLOS)飞行时,为无人机提供支持冗余的C2通信链路。如果需要创建额外的C2通信连接或更改现有数据连接的配置以进行C2通信,则5G网络会根据无人机系统的授权服务信息和C2通信中所需的QoS和优先级,修改或分配一个或多个C2通信流量的QoS流。

u011376987的博客 2053

跟我学C++中级篇——虚函数的性能

学习知识不是简单的为了会用,而是能够灵活的运用。要想灵活的运用,则必须掌握技术本质的内涵。只有把其内在体系掌握,才能在具体的场景上发挥其优势。这也是总说的从必然世界到自由世界的一个哲学问题。

fpcc的专栏 1374

微信群“智”变:扣子机器人无缝接入实战

本文介绍了如何将扣子(Coze)机器人接入微信群实现智能化管理。文章首先阐述了扣子机器人的自然语言处理、自动分类和多模态交互等功能特点,以及其深度学习模型和持续学习能力的技术优势。随后详细讲解了接入步骤:从微信公众号配置、扣子平台机器人创建,到使用Flask框架实现消息转发功能的关键代码。通过电商客服和技术社群两个实际案例,展示了扣子机器人在提升响应效率、优化社群运营方面的显著效果。最后展望了未来在智能推荐、多模态交互等领域的发展潜力,为微信群智能化管理提供了实用解决方案。

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 832

虚函数效率真的低吗?看起来只是多了一次函数调用,为什么都说它效率低呢?| 虚函数 | C++

在程序设计的世界里,有些概念看似简单,却常被误解。虚函数在面向对象编程中作为实现多态性的核心机制,常为初学者所推崇;然而在资深工程师眼中,其所引入的运行时开销与潜在的性能影响,亦常成为讨论与权衡的焦点。

1252

如何在白平衡标定种构建不同类型的白平衡色温坐标系

以各家芯片方案的白平衡色温坐标系为切入点,详细介绍了各家芯片色温坐标系构建的理论依旧;并解析了不同色温坐标系下的物理含义,提提出了多种不同的色温坐标系

大熊 960

仿真学习系列(四十二):Sigrity仿真之走线阻抗和耦合检查

在高速电路设计中,走线的阻抗和信号线之间的耦合是影响信号完整性的重要因素。设计中可能会出现多种情况,导致阻抗变化或不匹配,例如线宽的变化、跨层分割等。传统的人工检查方法常常不够高效且易忽视细节。借助仿真软件,可以快速定位问题区域,并进行精确分析,从而有效避免或减少信号反射和串扰带来的影响。

案例文章,高速信号 425

C++虚函数表,虚表指针,内存分布

虚函数表和内存分布那一块转载自:https://blog.twofei.com/496/ 虚函数效率转载自:https://www.cnblogs.com/rollenholt/articles/2023364.html 前言 大家都应该知道C++的精髓是虚函数吧? 虚函数带来的好处就是: 可以定义一个基类的指针, 其指向一个继承类, 当通过基类的指针去调用函数时, 可以在运行时决定该调用基...

qinrenzhi的博客 294

从 Token 到 Agent:一文串起 AI 大模型核心概念

摘要:本文系统解析了现代AI系统的八大核心概念:Token(语言处理的最小单位)、Context(AI的短期记忆)、Prompt(指令接口)、Tool(能力扩展器)、MCP(工具生态协议)、Agent(自主智能体)和AgentSkill(专业技能封装)。文章揭示了这些概念如何共同构成AI从基础语言理解到自主决策的技术脉络,重点阐述了Token对计算成本的影响、Prompt工程的重要性、Tool如何突破AI的能力边界,以及Agent如何通过"感知-规划-执行-反思"循环完成复杂任务。最后指

jundao1997的专栏 251

虚函数的效率问题

c++ 虚函数机制 效率问题 1,多一次查虚表过程 2,虚函数 效率低 是因为 执行过程中会跳转两次(首先找到对象的函数表,其次通过该函数表中存的虚函数表地址找到真正的执行地址),这样CPU运行的时候会跳转两次,而普通函数只跳一次。CPU每跳转一次,预取指令基本上就要作废

格物致知 1158

Diffusion Models扩散模型与深度学习(数学原理和代码解读)

​ 此前GANs霸占各大顶会很多年,DDPM的出现让人耳目一新!经过这两年的发展,Diffusion Models能在图像生成、超分辨率重建、点云生成、语音生成等领域达到SOTA。这篇文章旨在帮助没有了解过的读者入门,《Diffusion Models与深度学习专栏》已经写了将近三十篇文章,既有原理公式和必备基础知识的讲解,也有代码详细实战解读,还有前沿热门应用,欢迎读者订阅。

沉迷单车的追风少年 4万+

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

虚函数的实现机制

虚函数的实现机制 每个含有虚函数的类都有一张虚函数表。 在继承关系中,子类的虚函数表具有包含心,即父类的虚函数表肯定在子类中有一份完整的拷贝,一模一样。 从虚函数的实现机制来讲讲为何虚函数会影响效率 无论在何种情况,采用多态机制调用虚函数的时候都会比普通函数调用要慢,不管cpu缓存或其他机制做得多好。 现在cpu几经很强了,如果不是设计不合理和性能要求极高,一般虚函数的开销可以忽略。 当用基类指针调用虚函数的时候,能够根据指针所指的实际对象来选择到底是调用那个派生类对象的虚函数,对于这个问题的解就可以找

如果可以我想再爱一次的博客 746

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

qt 子类调用父类的函数_C++幕后故事(四)-- 虚函数的魅力

提出问题:我们讨论前提都是在windows 10 vs2013 debug模式下1.虚函数指针和虚表在哪里?2.我们如何手动调用虚函数?3.为什么只有在子类以父类的引用或者指针的形式才能出现多态?4.虚函数的调用为什么效率相比普通的成员函数较低?又具体低了多少?5.为什么构造函数和析构函数尽量不要调用虚函数?6.纯虚函数到底是什么?为什么禁止我调用?有什么办法可以绕编译器?7.看码说话class ...

weixin_39824191的博客 899

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

C++中虚函数工作原理详解

C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。 所谓泛型技术,比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议。 虚函数表(Virtual Table)来实现的。即一个类的虚函数的地址表。 注意:以下代码在64位系统通过,32位的把long改为int #i...

452

C++中的动态多态虚函数机制深度解析与性能权衡

虚函数的实现依赖于虚函数表(vtable),这是每个包含虚函数的类所拥有的一个隐藏数据结构。当通过基类指针或引用调用虚函数时,编译器会生成代码,通过vptr找到vtable,然后在vtable中找到正确的函数指针,最后通过该指针调用函数。在大多数应用中,虚函数的开销是可以接受的,但在性能关键的代码路径中,应考虑替代方案或优化策略。此外,现代编译器的优化技术如全程序分析和链接时优化(LTO)可以在某些情况下减少虚函数调用的开销,甚至可能将虚函数调用转换为直接调用。仅在真正需要运行时多态性时使用虚函数。

ynwxyuan的专栏 359

使用“override”声明的成员函数不能重写基类成员_面试必知必会|理解C++虚函数...

本文首发于:面试必知必会|理解C++虚函数微信公众号:后端技术指南针持续输出干货 欢迎关注 惊喜直达!0.前言在后端面试中语言特性的掌握直接决定面试成败,因此本公众号在在后续会持续输出编程语言的必知必会知识点系列。C++语言一直在增加很多新特性来提高使用者的便利性,但是每种特性都有复杂的背后实现,充分理解实现原理和设计原因,才能更好地掌握这种新特性。只要出发总会达到,只有出发才会到达,焦虑没用,学...

weixin_39840733的博客 2270

虚函数:从零开始

虚函数联系到多态,多态联系到继承。所以本文中都是在继承层次上做文章。没了继承,什么都没得谈。下面是小弟对C++的虚函数这玩意儿的理解。一, 什么是虚函数(如果不知道虚函数为何物,但有急切的想知道,那你就应该从这里开始)简单地说,那些被virtual关键字修饰的成员函数,就是虚函数。虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism),多态性是将接口与实

0011411的专栏 1076

多态实现的原理-多态的缺点-虚析构-纯虚函数

C++多态机制通过虚函数实现,父类和子类各自拥有虚函数列表,对象通过__vfptr指针指向对应虚函数表。子类继承父类虚函数表,重写时会覆盖父类虚函数,新增虚函数则追加到列表末尾。虚析构函数确保父类指针删除子类对象时正确调用子类析构。纯虚函数(抽象类)强制子类实现接口,但抽象类不能实例化。多态存在空间开销(每个对象携带虚表指针)、效率损失(间接调用)和安全隐患(私有虚函数可能被外部调用)等缺点。override和final关键字分别用于强制重写和禁止重写虚函数。

m0_60656600的博客 972

C++中虚函数工作原理和(虚)继承类的内存占用大小计算

一、虚函数的工作原理       虚函数的实现要求对象携带额外的信息,这些信息用于在运行时确定该对象应该调用哪一个虚函数。典型情况下,这一信息具有一种被称为 vptr(virtual table pointer,虚函数表指针)的指针的形式。vptr 指向一个被称为 vtbl(virtual table,虚函数表)的函数指针数组,每一个包含虚函数的类都关联到 vtbl。当一个对象调用了虚函数,实际

SzMing 796

虚函数VS虚拟继承:C++多重继承二义性破解与性能调优 -详解(附测试代码)

对于析构函数,同样存在这样的压抑效果,D类析构执行完后,根据继承声明顺序的反序调用C类的析构函数,C的析构函数执行完后并没有自动调用A的析构函数,而是接下来调用B的析构函数,最后调用A的析构函数。多重继承和虚拟继承对象模型较单一继承复杂的对象模型,造成了成员访问低效率,表现在两个方面:对象构造时 vptr 的多次设定,以及 this 指针的调整。在虚拟继承的结构中,最底层的派生类不仅需要显式调用中间层基类的构造函数,还要在初始化列表最开始调用顶层基类的构造函数。虚拟继承时派生类对象的构造和析构。

m0_74696257的博客 682
上一篇: 遇到多线程问题,关于MyDownload
下一篇: .mc文件
AstrayLinux
博客等级 码龄15年 55粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值