c++ - 为每个派生类优化(重新编译)继承虚方法

标签 c++ optimization g++ vtable

假设我们有一个“主”类,它有一个名为“Bulk”的方法来通过虚拟方法执行 N 次交互。

这个虚方法可以被很多类覆盖,但只能被覆盖一次。 出于性能原因,我们必须尽可能地减少调用/vtable 解析的成本。 (示例:++10Gb 网络数据包生成)

我解决这个问题的想法之一是使方法 Bulk 虚拟并“以某种方式”强制它​​在每个派生类上重新编译,因此我们可以只进行一次 VTABLE 搜索而不是 N 并且还可以从内联中获得一些改进/上交所/等。 然而,阅读 de ASM 我只得到一个通用的“批量”方法,它再次在 vtable 中搜索 N 次。

¿您知道有什么方法可以强制重新编译该方法(当然不需要将其代码复制粘贴到每个派生类上)或任何其他方法来减少调用和 VTABLE 搜索吗?我认为应该经常询问类似的要求,但我没有找到任何东西......

示例代码:

母版.hpp

#pragma once
#include <string>

class master
{
public:
    virtual unsigned Bulk(unsigned n)
    {
        unsigned ret = 0;
        for (int i = 0; i < 144; ++i)
            ret += once();

        return ret;
    }

    virtual unsigned once() = 0;
};

derived1.hpp

#pragma once
#include "master.hpp"

class derived1 final: public master
{
    virtual inline unsigned once() final { return 7; }
};

derived2.hpp

#pragma once
#include "master.hpp"

class derived2 final: public master
{
    virtual inline unsigned once() final { return 5; }
};

main.cpp

#include "derived1.hpp"
#include "derived2.hpp"
#include <iostream>
using namespace std;

int main()
{
    derived1 d1;
    derived2 d2;

    cout << d1.Bulk(144) << endl;
    cout << d2.Bulk(144) << endl;

    return 0;
}

我正在使用的编译命令:g++ main.cpp -S -O3 --std=gnu++17

编译的批量循环:

    movq    0(%rbp), %rax
    movq    %rbp, %rdi
    call    *8(%rax)
    addl    %eax, %r12d
    subl    $1, %ebx
    jne .L2

最佳答案

我不是很理解你的问题;)

但是,我建议在您不需要虚拟分派(dispatch)时避免虚拟分派(dispatch),而不是尝试围绕虚拟表进行优化(这是一个实现细节,因此优化不会是可移植的)。也许CRTP是一个选项。

以防万一你想多态地使用derivedX,你可以添加一个公共(public)基类:

#include <iostream>
#include <string>
using namespace std;

struct base {
    virtual std::string Bulk(unsigned n) = 0;
    virtual ~base(){}
};

template <typename T>
struct master : base {
    virtual std::string Bulk(unsigned n) {
        std::string ret = "";
        auto ptr = static_cast<T*>(this);
        for (int i = 0; i < n; ++i) ret += ptr->once();
        return ret;
    }
};

struct derived1 final : public master<derived1> {
    std::string once() { return "a"; }
};

struct derived2 final : public master<derived2> {
    std::string once() { return "b"; }
};

int main()
{
    derived1 d1;
    derived2 d2;

    cout << d1.Bulk(3) << endl;
    cout << d2.Bulk(3) << endl;
}

关于c++ - 为每个派生类优化(重新编译)继承虚方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65339464/

相关文章:

c++ - 做什么 ({});在 C++ 中是什么意思?

c++ - 删除动态内存时出现断言失败错误

c++ - 如何最好地集成生成的代码

c++ - 让本地符号走向全局

linux - 如何将编译器的所有输出捕获到文件中?

c++ - C++ dyld:未加载库-设置 '-L'后

c++ - 类型独立 vector 类成员

python - 为 scipy.optimize.fmin(和其他)设置收敛标准

mysql - 使用什么索引进行查询

mysql - 什么是删除旧记录的更快方法