相关疑难解决方法(0)

什么是"缓存友好"代码?

" 缓存不友好代码 "和" 缓存友好 "代码之间有什么区别?

如何确保编写高效缓存代码?

c++ memory performance caching cpu-cache

703
推荐指数
7
解决办法
14万
查看次数

在C++中使用接口的性能损失?

在C++中使用接口(抽象基类)时是否存在运行时性能损失?

c++ performance abstract-class virtual-functions

42
推荐指数
4
解决办法
1万
查看次数

C++中的AI应用程序:虚拟功能的成本是多少?有哪些可能的优化?

在我用C++编写的AI应用程序中,

  1. 没有太多的数值计算
  2. 有许多结构需要运行时多态性
  3. 通常,几个多态结构在计算过程中相互作用

在这种情况下,有没有任何优化技术?虽然我现在不打算优化应用程序,但为项目选择C++而不是Java的一个方面是提供更多的优势,以便能够使用非面向对象的方法(模板,过程,重载).

特别是,与虚拟功能相关的优化技术是什么?虚函数通过内存中的虚拟表实现.有没有办法将这些虚拟表预取到L2缓存上(从内存/ L2缓存中获取的成本正在增加)?

除此之外,C++中的数据局部技术是否有很好的参考?这些技术将减少数据提取到计算所需的L2高速缓存的等待时间.

更新:另请参阅以下相关论坛:界面的性能惩罚,几个基类的级别

c++ optimization

16
推荐指数
2
解决办法
5353
查看次数

连续存储多态类型

我有兴趣知道是否有任何可行的方法来连续存储多态对象数组,这样virtual可以合法地调用公共基础上的方法(并将调度到子类中正确的重写方法).

例如,考虑以下类:

struct B {
  int common;
  int getCommon() { return common; }
  virtual int getVirtual() const = 0;
}

struct D1 : B {
  virtual int getVirtual final const { return 5 };
}

struct D2 : B {
  int d2int;
  virtual int getVirtual final const { return d2int };
}
Run Code Online (Sandbox Code Playgroud)

我想分配一个连续的D1和D2对象数组,并将它们视为B对象,包括调用getVirtual()哪些将根据对象类型委托给适当的方法.从概念上讲,这似乎是可能的:每个对象通常通过嵌入的vtable指针知道它的类型,因此您可以想象,将n个对象存储在数组中,并使用放置和初始化对象,并将指针转换为.不过,我很确定演员不合法.n * max(sizeof(D1), sizeof(D2)) unsigned charnewdeleteunsigned charB*

人们还可以想象创建一个联盟,如:

union Both { …
Run Code Online (Sandbox Code Playgroud)

c++ polymorphism virtual-functions

13
推荐指数
1
解决办法
793
查看次数

避免虚拟功能

因此,假设我想创建一系列类,每个类都具有相同的成员函数.我们来调用这个函数吧

void doYourJob();
Run Code Online (Sandbox Code Playgroud)

我想最终把所有这些类放到同一个容器中,这样我就可以遍历它们并让每个类都执行'doYourJob()'

显而易见的解决方案是使用该函数创建一个抽象类

 virtual void doYourJob();
Run Code Online (Sandbox Code Playgroud)

但我这样做犹豫不决.这是一个耗时的计划,虚拟功能可以大大提高它.此外,这个函数是类中唯一相互共同的函数,并且doYourJob对每个类的完全不同.

有没有办法避免使用具有虚函数的抽象类,或者我将不得不吮吸它?

c++ code-organization

9
推荐指数
2
解决办法
5240
查看次数

为什么链接到librt在g ++和clang之间交换性能?

我刚从@ tony-d 找到了这个答案,用一个基准代码来测试虚函数调用开销.我查了基准使用g++:

$ g++ -O2 -o vdt vdt.cpp -lrt
$ ./vdt
virtual dispatch: 150000000 0.128562
switched: 150000000 0.0803207
overheads: 150000000 0.0543323
...
Run Code Online (Sandbox Code Playgroud)

我的表现更好(他的比例约为2),但后来我查了一下clang:

$ clang++-3.7 -O2 -o vdt vdt.cpp -lrt
$ ./vdt
virtual dispatch: 150000000 0.462368
switched: 150000000 0.0569544
overheads: 150000000 0.0509332
...
Run Code Online (Sandbox Code Playgroud)

现在这个比例上升到70左右!

然后我注意到了-lrt命令行参数,经过一些谷歌搜索后,librt我尝试了没有它g++clang:

$ g++ -O2 -o vdt vdt.cpp
$ ./vdt
virtual dispatch: 150000000 0.4661
switched: 150000000 0.0815865
overheads: 150000000 0.0543611
...
$ …
Run Code Online (Sandbox Code Playgroud)

c++ benchmarking librt

5
推荐指数
1
解决办法
270
查看次数

没有虚函数的命令模式(C++)

出于性能原因,我使用Curiously Reoccuring模板模式来避免虚函数.我有很多执行数百万次的小命令.我试图将其纳入命令模式.我想在队列中添加大量命令,然后迭代执行每个命令.每个命令使用CRTP来避免虚函数.我遇到的问题是Command模式通常使用指针向量来实现.但是当Command类被模板化时,很难传递通用的Command指针.我不是C++专家,所以也许有一种显而易见的方法来存储模板化命令对象的向量?我一直试图使用类似的东西:

boost:ptr_vector commands;
AddCommand(Command* command) {
  commands.push_back(command);
}
Run Code Online (Sandbox Code Playgroud)

问题是Command不是类型,因此Command* command给出了编译错误.我需要使用Command<CommandType>,但这不起作用,因为我需要队列来保存不同类型的命令.

任何解决方案的想法?或者虚拟功能是我唯一的选择吗?

增加:命令对象是蒙特卡罗模拟算法的一部分.所以你可能有,Command是来自正态分布的随机数,其中正态分布的参数是类的一部分.所以命令模式非常合适.我按特定顺序对需要维护状态的函数进行了大量调用.

c++ performance templates design-patterns virtual-functions

4
推荐指数
1
解决办法
2068
查看次数

用c ++快速实现简单,虚拟,观察者类型的模式?

我正在努力尝试使用枚举和大量的宏观魔法来实现vtable的替代品,这种魔法真的开始让我的大脑混乱.我开始认为我没有走正确的道路,因为代码变得更加丑陋和丑陋,并且无论如何都不适合生产.

如何使用最少量的重定向/操作实现以下代码的模式?

它必须在标准的c ++中完成,最多17个.

class A{
    virtual void Update() = 0; // A is so pure *¬*
};

class B: public A
{
    override void Update() final
    {
        // DO B STUFF
    }
}

class C: public A
{
    override void Update() final
    {
        // DO C STUFF
    }
}

// class...

int main()
{
    std::vector<A*> vecA{};

    // Insert instances of B, C, ..., into vecA

    for(auto a: vecA) // This for will be inside a main loop
        a->Update(); // …
Run Code Online (Sandbox Code Playgroud)

c++ enums virtual-functions micro-optimization dispatch

3
推荐指数
1
解决办法
357
查看次数

虚拟或类型转换

我有个问题.我正在尝试创建代码来更新我的游戏,但我陷入了"两难".我不想使用虚拟和它的唯一原因是我在谈论的每个人(在论坛,聊天,朋友)说虚拟使代码真的很慢,所以我做了一个研究,发现它做的查找vtable可以将性能降低近一半.因此,我将它用于不需要每帧更新的任务.一切正常,直到我得到更新/渲染功能.然后我开始考虑寻找解决方法.有了一个想法,但首先我想问一下那些知道那个人的人在实施之前.

我的游戏引擎非常受事件驱动.我可以使用子系统之间的事件(图形,UI,脚本)发送任何类型的数据.所以,我正在考虑每帧发送一个事件"renderScene".这对我来说听起来不错,但是有一个问题.事件处理程序的结构并不是很好,我现在真的不想改进它,因为它做得非常不错,我的目标是完成我的游戏,而不是修理引擎而永远不会完成它(碰巧我,所以不想再回到它了.

我的事件处理程序有一个函数将事件注册到函数(我称之为处理程序).但是这个函数的问题是,我需要做函数绑定和东西来注册成员函数.所以,我找到了一个解决方法 - 我创建一个静态函数并从中调用成员函数.这就是静态函数的样子:

void GraphicsSubsystem::renderScene(Subsystem * subsystem, Event * event) {
   GraphicsSubsystem * graphics = static_cast<GraphicsSubsystem *>(subsystem);
   graphics->renderScene();
}

void ScriptingSubsystem::runLine(Subsystem * subsystem, Event * event) {
   ScriptingSubsystem * scripting = static_cast<ScriptingSubsystem *>(subsystem);
   Event1<String> * e = static_cast<Event1<String> *>(event);
   scripting->runLine(e->getArg());
}
Run Code Online (Sandbox Code Playgroud)

参数始终是抽象子系统类和基本事件类.该runLine功能我没有问题,因为铸造我不运行的每个机架上的一行代码.但是,renderScene函数让我有点不舒服.

tl;博士,这是我的问题.静态构建每个帧上的对象比在每个帧上调用虚函数更快吗?

c++ polymorphism casting event-handling

2
推荐指数
1
解决办法
255
查看次数

C++ 使用纯虚函数实例化抽象类的子类

我有一个抽象类,例如Animal。Animal 有一个纯虚函数eat,如果每个动物不想挨饿,就必须实现它。我确保只能通过这种方式实例化 Animal 的孩子:

动物.hpp

class Animal
{

public:

    enum eAnimal{
        CAT=0,
        DOG=1,
        BIRD=2
    };

    // Instantiates the desired animal.
    static Animal GetAnimal(const int animal);

    virtual void Eat() const = 0;

protected:

    Animal();
};
Run Code Online (Sandbox Code Playgroud)

动物.cpp

Animal Animal::GetAnimal(const int animal)
{
    switch(animal)
    {
    case CAT:
        return Cat();
    case DOG:
        return Dog();
    case BIRD:
        return Bird();
    default:
        cerr << "Animal not recognized." << endl;
        exit(-1);
    }
}

Animal::Animal()
{}
Run Code Online (Sandbox Code Playgroud)

有了这个,将是:

猫.hpp

class Cat : public Animal …
Run Code Online (Sandbox Code Playgroud)

c++ polymorphism abstract-class return-by-value

1
推荐指数
1
解决办法
1252
查看次数