gpt4 book ai didi

c++ - 您可以在 C++ 中缓存虚函数查找吗?

转载 作者:IT老高 更新时间:2023-10-28 12:34:17 38 4
gpt4 key购买 nike

假设我在抽象基类指针 mypointer->foo() 上有一个虚函数调用 foo()。当我的应用程序启动时,根据文件的内容,它选择实例化一个特定的具体类并将 mypointer 分配给该实例。在应用程序的剩余生命周期中,mypointer 将始终指向该具体类型的对象。我无法知道这个具体类型是什么(它可能由动态加载库中的工厂实例化)。我只知道在第一次创建具体类型的实例后类型将保持不变。指针可能并不总是指向同一个对象,但该对象总是具有相同的具体类型。请注意,从技术上讲,类型是在“运行时”确定的,因为它基于文件的内容,但在“启动”(加载文件)之后,类型是固定的。

但是,在 C++ 中,每次在应用程序的整个持续时间内调用 foo 时,我都会支付虚函数查找成本。编译器无法优化查找,因为它无法知 Prop 体类型在运行时不会改变(即使它是有史以来最神奇的编译器,它也无法推测动态加载的行为图书馆)。在 Java 或 .NET 等 JIT 编译语言中,JIT 可以检测到重复使用相同的类型并执行 inline cacheing .我基本上是在寻找一种方法来手动为 C++ 中的特定指针执行此操作。

C++ 中有没有办法缓存这个查找?我意识到解决方案可能非常骇人听闻。如果可以编写发现 ABI/编译器相关方面的配置测试,即使不是真正可移植,我也愿意接受 ABI/编译器特定的 hack。

更新:对于反对者:如果这不值得优化,那么我怀疑现代 JIT 会这样做。您是否认为 Sun 和 MS 的工程师正在浪费时间实现内联缓存,并且没有对其进行基准测试以确保有改进?

最佳答案

虚函数调用有两个开销:vtable 查找和函数调用。

vtable 查找已由硬件处理。现代 CPU(假设您不是在非常简单的嵌入式 CPU 上工作)将在其分支预测器中预测虚拟函数的地址,并推测性地与数组查找并行执行它。 vtable 查找与函数的推测执行并行发生的事实意味着,在您描述的情况下在循环中执行时,与直接的非内联函数调用相比,虚函数调用的开销几乎为零.

我过去实际上已经对此进行了测试,尽管使用的是 D 编程语言,而不是 C++。当在编译器设置中禁用内联并且我在循环中调用同一个函数数百万次时,无论该函数是否为虚拟函数,时间都在彼此的 epsilon 内。

虚函数的第二个也是更重要的代价是它们在大多数情况下会阻止函数的内联。这比听起来更重要,因为内联是一种优化,它可以启用其他几种优化,例如在某些情况下进行常量折叠。如果不重新编译代码,就无法内联函数。 JIT 解决了这个问题,因为它们在您的应用程序执行期间不断地重新编译代码。

关于c++ - 您可以在 C++ 中缓存虚函数查找吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2141726/

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