一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - C/C++ - 詳解C++編譯器優(yōu)化技術(shù)

詳解C++編譯器優(yōu)化技術(shù)

2021-11-12 16:01可可西 C/C++

現(xiàn)代編譯器缺省會(huì)使用RVO(return value optimization,返回值優(yōu)化)、NRVO(named return value optimization、命名返回值優(yōu)化)和復(fù)制省略(Copy elision)技術(shù),來減少拷貝次數(shù)來提升代碼的運(yùn)行效率。

前言

注1:vc6、vs沒有提供編譯選項(xiàng)來關(guān)閉該優(yōu)化,無論是debug還是release都會(huì)進(jìn)行RVO和復(fù)制省略優(yōu)化

注2:vc6、vs2005以下及vs2005+ Debug上不支持NRVO優(yōu)化,vs2005+ Release支持NRVO優(yōu)化

注3:g++支持這三種優(yōu)化,并且可通過編譯選項(xiàng):-fno-elide-constructors來關(guān)閉優(yōu)化

RVO

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <stdio.h>
class A
{
public:
    A()
    {
        printf("%p construct\n", this);
    }
    A(const A& cp)
    {
        printf("%p copy construct\n", this);
    }
    ~A()
    {
        printf("%p destruct\n", this);
    }
};
 
A GetA()
{
    return A();
}
 
int main()
{
    {
        A a = GetA();
    }
 
    return 0;
}

在g++和vc6、vs中,上述代碼僅僅只會(huì)調(diào)用一次構(gòu)造函數(shù)和析構(gòu)函數(shù) ,輸出結(jié)果如下:

0x7ffe9d1edd0f construct

0x7ffe9d1edd0f destruct

在g++中,加上-fno-elide-constructors選項(xiàng)關(guān)閉優(yōu)化后,輸出結(jié)果如下:

0x7ffc46947d4f construct  // 在函數(shù)GetA中,調(diào)用無參構(gòu)造函數(shù)A()構(gòu)造出一個(gè)臨時(shí)變量temp

0x7ffc46947d7f copy construct // 函數(shù)GetA return語句處,把臨時(shí)變量temp做為參數(shù)傳入并調(diào)用拷貝構(gòu)造函數(shù)A(const A& cp)將返回值ret構(gòu)造出來

0x7ffc46947d4f destruct // 函數(shù)GetA執(zhí)行完return語句后,臨時(shí)變量temp生命周期結(jié)束,調(diào)用其析構(gòu)函數(shù)~A()

0x7ffc46947d7e copy construct // 函數(shù)GetA調(diào)用結(jié)束,返回上層main函數(shù)后,把返回值變量ret做為參數(shù)傳入并調(diào)用拷貝構(gòu)造函數(shù)A(const A& cp)將變量A a構(gòu)造出來

0x7ffc46947d7f destruct // A a = GetA()語句結(jié)束后,返回值ret生命周期結(jié)束,調(diào)用其析構(gòu)函數(shù)~A()

0x7ffc46947d7e destruct // A a要離開作用域,生命周期結(jié)束,調(diào)用其析構(gòu)函數(shù)~A()

注:臨時(shí)變量temp、返回值ret均為匿名變量

下面用c++代碼模擬一下其優(yōu)化行為:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <new>
A& GetA(void* p)
{
    //由于p的內(nèi)存是從外部傳入的,函數(shù)返回后仍然有效,因此返回值可為A&
    //vs中,以下代碼還可以寫成:
    // A& o = *((A*)p);
    // o.A::A();
    // return o;
    return *new (p) A(); // placement new
}
 
int main()
{
    {
        char buf[sizeof(A)];
        A& a = GetA(buf);
        a.~A();
    }
 
    return 0;
}

NRVO

g++編譯器、vs2005+ Release(開啟/O2及以上優(yōu)化開關(guān))

修改上述代碼,將GetA的實(shí)現(xiàn)修改成:

?
1
2
3
4
5
A GetA()
{
    A o;
    return o;
}

在g++、vs2005+ Release中,上述代碼也僅僅只會(huì)調(diào)用一次構(gòu)造函數(shù)和析構(gòu)函數(shù) ,輸出結(jié)果如下:

0x7ffe9d1edd0f construct

0x7ffe9d1edd0f destruct

g++加上-fno-elide-constructors選項(xiàng)關(guān)閉優(yōu)化后,和上述結(jié)果一樣

0x7ffc46947d4f construct

0x7ffc46947d7f copy construct

0x7ffc46947d4f destruct

0x7ffc46947d7e copy construct

0x7ffc46947d7f destruct

0x7ffc46947d7e destruct

但在vc6、vs2005以下、vs2005+ Debug中,沒有進(jìn)行NRVO優(yōu)化,輸出結(jié)果為:

18fec4 construct  // 在函數(shù)GetA中,調(diào)用無參構(gòu)造函數(shù)A()構(gòu)造出一個(gè)臨時(shí)變量o

18ff44 copy construct  // 函數(shù)GetA return語句處,把臨時(shí)變量o做為參數(shù)傳入并調(diào)用拷貝構(gòu)造函數(shù)A(const A& cp)將返回值ret構(gòu)造出來

18fec4 destruct  // 函數(shù)GetA執(zhí)行完return語句后,臨時(shí)變量o生命周期結(jié)束,調(diào)用其析構(gòu)函數(shù)~A()

18ff44 destruct // A a要離開作用域,生命周期結(jié)束,調(diào)用其析構(gòu)函數(shù)~A()

下面用c++代碼模擬一下vc6、vs2005以下、vs2005+ Debug上的行為:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <new>
A& GetA(void* p)
{
    A o;
    //由于p的內(nèi)存是從外部傳入的,函數(shù)返回后仍然有效,因此返回值可為A&
    //vs中,以下代碼還可以寫成:
    // A& t = *((A*)p);
    // t.A::A(o);
    // return t;
    return *new (p) A(o); // placement new
}
 
int main()
{
    {
        char buf[sizeof(A)];
        A& a = GetA(buf);
        a.~A();
    }
 
    return 0;
}

注:與g++、vs2005+ Release相比,vc6、vs2005以下、vs2005+ Debug只優(yōu)化掉了返回值到變量a的拷貝,命名局部變量o沒有被優(yōu)化掉,所以最后一共有2次構(gòu)造和析構(gòu)的調(diào)用

復(fù)制省略

典型情況是:調(diào)用構(gòu)造函數(shù)進(jìn)行值類型傳參

?
1
2
3
4
5
6
7
8
9
10
11
12
void Func(A a)
{
}
 
int main()
{
    {
        Func(A());
    }
 
    return 0;
}

在g++和vc6、vs中,上述代碼僅僅只會(huì)調(diào)用一次構(gòu)造函數(shù)和析構(gòu)函數(shù) ,輸出結(jié)果如下:

0x7ffeb5148d0f construct

0x7ffeb5148d0f destruct

在g++中,加上-fno-elide-constructors選項(xiàng)關(guān)閉優(yōu)化后,輸出結(jié)果如下:

0x7ffc53c141ef construct   // 在main函數(shù)中,調(diào)用無參構(gòu)造函數(shù)構(gòu)造實(shí)參變量o

0x7ffc53c141ee copy construct // 調(diào)用Func函數(shù)后,將實(shí)參變量o做為參數(shù)傳入并調(diào)用拷貝構(gòu)造函數(shù)A(const A& cp)將形參變量a構(gòu)造出來

0x7ffc53c141ee destruct // 函數(shù)Func執(zhí)行完后,形參變量a生命周期結(jié)束,調(diào)用其析構(gòu)函數(shù)~A()

0x7ffc53c141ef destruct // 返回main函數(shù)后,實(shí)參變量o要離開作用域,生命周期結(jié)束,調(diào)用其析構(gòu)函數(shù)~A()

下面用c++代碼模擬一下其優(yōu)化行為:

?
1
2
3
4
5
6
7
8
9
10
11
12
void Func(const A& a)
{
}
 
int main()
{
    {
        Func(A());
    }
 
    return 0;
}

優(yōu)化失效的情況

開啟g++優(yōu)化,得到以下各種失效情況的輸出結(jié)果:

(1)根據(jù)不同的條件分支,返回不同變量

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
A GetA(bool bflag)
{
    A a1, a2;
    if (bflag)
        return a1;
    return a2;
}
 
int main()
{
    A a = GetA(true);
 
    return 0;
}

0x7ffc3cca324f construct

0x7ffc3cca324e construct

0x7ffc3cca327f copy construct

0x7ffc3cca324e destruct

0x7ffc3cca324f destruct

0x7ffc3cca327f destruct

注1:2次缺省構(gòu)造函數(shù)調(diào)用:用于構(gòu)造a1、a2

注2:1次拷貝構(gòu)造函數(shù)調(diào)用:用于拷貝構(gòu)造返回值

注3:這兒仍然用右值引用優(yōu)化掉了一次拷貝函數(shù)調(diào)用:返回值賦值給a

(2)返回參數(shù)變量

(3)返回全局變量

(4)返回復(fù)合數(shù)據(jù)類型中的成員變量

(5)返回值賦值給已構(gòu)造好的變量(此時(shí)會(huì)調(diào)用operator==賦值運(yùn)算符)

以上就是詳解C++編譯器優(yōu)化技術(shù)的詳細(xì)內(nèi)容,更多關(guān)于C++編譯器優(yōu)化技術(shù)的資料請(qǐng)關(guān)注服務(wù)器之家其它相關(guān)文章!

原文鏈接:https://www.cnblogs.com/kekec/p/11303391.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 青青成人福利国产在线视频 | 99久热只有精品视频免费观看17 | 猛吸奶水的老汉 | 日本阿v精品视频在线观看 日本xxx片免费高清在线 | 亚洲+欧美+国产+综合 | 亚洲好视频 | 亚洲国产精品久久丫 | 亚洲精品123区在线观看 | 欧美精品一二三区 | 久久中文字幕无线观看 | 金牛网155755水心论坛黄大父母 | 免费老外的毛片清高 | 日日摸日日碰夜夜爽97纠 | 欧美亚洲桃花综合 | 天天综合色天天综合色sb | 日本欧美强乱视频在线 | 日本公乱妇视频 | 动漫女性扒开尿口羞羞漫画 | 调教小龙女| 99er视频| 调教扩张宫颈女人惨叫 | 超级乱淫变态伦短篇小说全集 | 3d动漫美女被吸乳羞羞视频 | 垫底辣妹免费观看完整版 | 99热精品在线播放 | 日本高清在线播放 | 黄www片 | 成人在线播放 | 国产成人精品免费 | 吉川爱美与黑人解禁 | 国产日韩精品一区二区在线观看播放 | 久久青草费线频观看国产 | 第一福利在线视频 | 女人又色又爽又黄 | 爱豆传媒最新视频国产 | 欧美成人中文字幕 | 欧美日韩精品乱国产538 | 成 人 亚洲 综合天堂 | 日本成熟bbxxxxxxxx | 99最新网址| 紧身裙女教师波多野结衣 |