簡體   English   中英

虛函數調用始終比正常函數調用快。為什么?

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

我編寫了以下程序來測試我的機器上虛擬功能的成本:

#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;
}

結果與我的預期相反:虛函數一直更快。 例如,這是我通過NUM_ITER = 10000000000獲得的輸出之一:

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

通過對生成的匯編程序文件的分析,我可以確認編譯器沒有優化任何重要的東西。 我使用GCC-4.7有以下選項:

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

為什么虛函數調用更快? 或者為什么非虛函數調用較慢? 分支預測變得如此好嗎? 或許它只是我的機器。 也許有人也可以測試和發布他的時間?

嘗試在每次調用run()之前global_a

void run()
{
    global_a = 2;

    ...
}

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

    ...
}

不確定這是否會產生任何影響,但並非所有數學運算都花費相同的時間!

編譯器可能足夠聰明,可以看到虛函數調用全局函數spin()並將它們虛擬化。 這些電話也可能被內聯。

檢查一下

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM