简体   繁体   English

虚函数调用始终比正常函数调用快。为什么?

[英]Virtual function call consistently faster than normal function call. Why?

I wrote the following program to test how much virtual functions cost on my machine: 我编写了以下程序来测试我的机器上虚拟功能的成本:

#include <iostream>
#include <ctime>
#define NUM_ITER 10000000000
//   5 seconds = 1000000000

static volatile int global_a;

void spin()
{
    int a = global_a;
    int b = a*a;
    int c = a+5;
    int d = a^b^c;
    global_a = b*d;
}

struct A {
    virtual void a() = 0;
};

struct B : A {
    virtual void a() { spin(); }
};

struct C : A {
    virtual void a() { spin(); }
};

void run_A1(A* a)
{
    a->a();
}

void run_A(A* a)
{
    for (long long i = 0; i < NUM_ITER; i++) {
        run_A1(a);
    }
}

void run()
{
    for (long long i = 0; i < NUM_ITER; i++) {
        spin();
    }
}

int main()
{
    global_a = 2;

    A* a1 = new B;
    A* a2 = new C;

    std::clock_t c_begin, c_end;

    c_begin = std::clock();
    run_A(a1);
    c_end = std::clock();

    std::cout << "Virtual | CPU time used: "
              << 1000.0 * (c_end-c_begin) / CLOCKS_PER_SEC
              << " ms\n";

    c_begin = std::clock();
    run_A(a2);
    c_end = std::clock();

    std::cout << "Virtual | CPU time used: "
              << 1000.0 * (c_end-c_begin) / CLOCKS_PER_SEC
              << " ms\n";

    c_begin = std::clock();
    run();
    c_end = std::clock();

    std::cout << "Normal  | CPU time used: "
              << 1000.0 * (c_end-c_begin) / CLOCKS_PER_SEC
              << " ms\n";

    delete a1;
    delete a2;
}

The results were opposite than I expected: the virtual functions were consistently faster. 结果与我的预期相反:虚函数一直更快。 For example, this is one of the outputs I got with NUM_ITER = 10000000000 : 例如,这是我通过NUM_ITER = 10000000000获得的输出之一:

Virtual | CPU time used: 49600 ms
Virtual | CPU time used: 50270 ms
Normal  | CPU time used: 52890 ms

From the analysis of the resulting assembler file I can confirm that the compiler hasn't optimized out anything important. 通过对生成的汇编程序文件的分析,我可以确认编译器没有优化任何重要的东西。 I've used GCC-4.7 with the following options: 我使用GCC-4.7有以下选项:

g++ -O3 -std=c++11 -save-temps -masm=intel -g0 -fno-exceptions -fno-inline test.cc -o test

Why are the virtual function calls faster? 为什么虚函数调用更快? Or why are the non-virtual function calls slower? 或者为什么非虚函数调用较慢? Have the branch predictors become so good? 分支预测变得如此好吗? Or maybe it's just my machine. 或许它只是我的机器。 Maybe someone could also test and post his timings? 也许有人也可以测试和发布他的时间?

Try reseting global_a before each call to run() : 尝试在每次调用run()之前global_a

void run()
{
    global_a = 2;

    ...
}

void run_A(A *a)
{    
    global_a = 2;

    ...
}

Not sure if this is having any impact, but not all mathematical operations take the same amount of time! 不确定这是否会产生任何影响,但并非所有数学运算都花费相同的时间!

The compiler might be smart enough to see that the virtual functions call a global function spin() and devirtualize them. 编译器可能足够聪明,可以看到虚函数调用全局函数spin()并将它们虚拟化。 The calls probably get inlined too. 这些电话也可能被内联。

Check this . 检查一下

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM