gpt4 book ai didi

运行时的 C++ 去虚拟化?

转载 作者:行者123 更新时间:2023-11-30 03:53:04 25 4
gpt4 key购买 nike

是否有技术/库允许具有类层次结构(具有 virtual 函数)的灵 active ,一旦对象类型在运行时被确定,允许函数调用的去虚拟化?

举个简单的例子,假设我有一个程序,它从一些配置文件中读取形状类型(圆形、矩形、三角形等)以构建所述形状的一些数据结构(例如,vector<shape*>):

class shape {
public:
virtual void draw() const = 0;
// ...
};

class circle : public shape {
public:
void draw() const;
// ...
};

// ...
vector<shape*> shapes;

显然,如果我想绘制所有形状,我可以这样做:

for ( auto&& s : shapes )
s->draw();

每次这样的迭代超过shapes完成了,一个virtual进行函数调用以调用 draw()对于每个形状。

但是假设一次shapes被创建后,它永远不会在程序的生命周期内再次改变;并进一步假设 draw()将被调用 很多 次。如果知道实际 形状后,有一种方法可以“去虚拟化”对draw() 的调用,那就太好了。 在运行时

我知道去虚拟化的优化技术virtual编译时调用函数,但我问这个问题。

如果有一个聪明的 hack 可以直接在 C++ 中执行此操作,我会非常感到惊讶,因为执行此操作的一种方法是在运行时修改内存中的机器代码。但是是否有一些 C++ 库可以实现这样的功能?

我想像这样的事情可能可以通过 LLVM 实现,因为它允许在运行时生成机器代码。有人为此使用过 LLVM 吗?也许是在 LLVM 之上分层的框架?

注意:解决方案必须跨平台,即至少使用 gcc/clang VC++。

最佳答案

我相当确定没有魔法这样的东西,“这里的编译器,没有我要定义的子类,这个列表也不会改变,所以消除虚函数调用开销” 之类的东西。

您可以做的一件事可以帮助在性能极其关键的情况下进行虚拟调用,即按子类型对形状列表进行排序。例如,您想要重新排列这些类型,而不是圆形、矩形、三角形、矩形、三角形、正方形等子类型的零星模式,以形成如下形式:圆形、圆形、圆形、圆形、...、方形、 square, square, ..., 等等。这有效地优化了分支预测。我不知道这种方法是否仍然适用或在最新的架构和优化器中产生了很多里程,但至少在不久前我还活着的时候它非常有用。

关于 JIT,我一直在探索那个领域。我不一定会建议尝试找到 JIT 解决方案来神奇地使您的 C++ 代码更快。

相反,我一直在探索它,因为我的软件已经有了一种特定领域的语言,一种可视化的节点 GUI 编程语言,您可以在节点(函数)之间绘制连接,而不是编写代码来制作新的东西,比如着色器和图像过滤器(类似于 Unreal Engine 4 的 BluePrint)。它目前远不及手写 native 代码那么快,这就是为什么我有兴趣探索代码生成/JIT 路线。它目前更像是一个解释器。

我已经为这些尝试了 Tiny C 和 LCC,但我发现对它们相当失望的一件事是它们的优化器不如您的商业生产编译器那么复杂。我经常得到的结果平均比 MSVC 或 GCC 慢 3 到 4 倍。它们在其他方面都很棒,因为它们非常轻巧且易于嵌入。

LLVM 看起来是一个绝妙的搭配,只是它非常庞大。在我们的核心层区域,我们有这种老派审美,其中旨在最大程度地重用的代码应该尽可能少地重用(以避免对外部包的零星依赖)。我很难将其降低到足以通过这些标准的轻量级,但我仍在研究它。

关于运行时的 C++ 去虚拟化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30314645/

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