回电的代价是多少?

时间:2010-06-21 09:06:19

标签: c visual-c++

我正在创建一个渲染引擎。以及我创建任务管理系统的两种方式。创建我自己的自定义回调,在渲染之前和之后调用,或者实现一个任务管理系统,在这个系统中,我必须从父TaskClass派生一个类,然后将它扔进队列。

老实说,我觉得创建回调更好,因为它允许我创建独立于实际渲染引擎的任务管理子系统。这使我可以更专注于渲染引擎,并在以后担心任务管理。

但我的问题是......“使用回调是否代价高昂?” 这种做法在处理器密集型环境中很常见,例如游戏引擎。

7 个答案:

答案 0 :(得分:5)

首先,昂贵是相对的,如果你将这些回调称为10000Hz,是的,一些回调实现可能成本太高。但是,一个简单的基于函数指针的回调实际上几乎没有开销。

但最重要的是:这是一个过早优化的例子,当然,因为它看起来你平均每场只能在平均30 fps的游戏中调用这些回调60次。在大多数游戏中,性能问题会更加重要。从一种方法开始,在遇到性能问题时对其进行分析,如果确实不够,则优化它。无论如何,你可能会在数学或AI函数上放松更多的cpu周期。

最后:在许多游戏中,瓶颈是GPU,而不是CPU;)。

答案 1 :(得分:5)

关于在C中使用函数指针执行回调的成本,对于这个小片段

void func1() { }

void func2() 
{
  void (*funcptr)() = func1;

  func1();
  funcptr();
}

gcc -S为func2的主体生成以下汇编程序指令:

movq $func1, -8(%rbp)
movl $0, %eax
call func1
movq -8(%rbp), %rdx
movl $0, %eax
call *%rdx

因此,正如预期的那样,您只需支付指针间接费用,即您不必担心性能。

答案 2 :(得分:2)

回调是一个函数指针。通过一个函数调用函数并不是很昂贵,但肯定会产生一些开销 - 函数至少不会内联。

只有你能负担得起才能证明 - 写一个小的测试程序并对其进行分析。根据您调用该函数的频率,开销将占用更少或更多的处理器时间。没有剖析预测和分析是不值得的。

答案 3 :(得分:0)

当它们不涉及闭包时,回调非常便宜。

涉及闭包的回调要贵一些。

答案 4 :(得分:0)

回调本身并不昂贵,但应注意不要做太多的计算。通常回调发布消息,给出信号量/信号等并停止。

答案 5 :(得分:0)

  

“使用回调是否代价高昂?”

它可以与调用虚函数的成本一样小。

根据您的环境,它可能更昂贵:例如,如果它是从内核模式到用户模式的回调,那么您可能需要做一些聪明和/或昂贵的事情来实现明显的环转换。

回调的一个问题是锁:如果您的代码是多线程和/或线程安全的,那么如果您在调用回调时拥有任何锁(那么取决于回调中的用户代码,例如尝试获得更多的锁)你可能会陷入僵局。

答案 6 :(得分:0)

如果您正在使用Visual Studio并查看任务管理系统,请查看VS 2010 here中的并发运行时,并行模式库和代理库。

您不需要构建自己的任务系统,也可以构建自己的任务系统。