iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >详解C++编译器优化技术
  • 737
分享到

详解C++编译器优化技术

2024-04-02 19:04:59 737人浏览 八月长安
摘要

目录前言RVONRVO复制省略优化失效的情况前言 注1:vc6、vs没有提供编译选项来关闭该优化,无论是debug还是release都会进行RVO和复制省略优化 注2:vc6、vs2

前言

注1:vc6、vs没有提供编译选项来关闭该优化,无论是debug还是release都会进行RVO和复制省略优化

注2:vc6、vs2005以下及vs2005+ Debug上不支持NRVO优化,vs2005+ Release支持NRVO优化

注3:g++支持这三种优化,并且可通过编译选项:-fno-elide-constructors来关闭优化

RVO


#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中,上述代码仅仅只会调用一次构造函数和析构函数 ,输出结果如下:

0x7ffe9d1edd0f construct

0x7ffe9d1edd0f destruct

在g++中,加上-fno-elide-constructors选项关闭优化后,输出结果如下:

0x7ffc46947d4f construct  // 在函数GetA中,调用无参构造函数A()构造出一个临时变量temp

0x7ffc46947d7f copy construct // 函数GetA return语句处,把临时变量temp做为参数传入并调用拷贝构造函数A(const A& cp)将返回值ret构造出来

0x7ffc46947d4f destruct // 函数GetA执行完return语句后,临时变量temp生命周期结束,调用其析构函数~A()

0x7ffc46947d7e copy construct // 函数GetA调用结束,返回上层main函数后,把返回值变量ret做为参数传入并调用拷贝构造函数A(const A& cp)将变量A a构造出来

0x7ffc46947d7f destruct // A a = GetA()语句结束后,返回值ret生命周期结束,调用其析构函数~A()

0x7ffc46947d7e destruct // A a要离开作用域,生命周期结束,调用其析构函数~A()

注:临时变量temp、返回值ret均为匿名变量

下面用c++代码模拟一下其优化行为:


#include <new>
A& GetA(void* p)
{
    //由于p的内存是从外部传入的,函数返回后仍然有效,因此返回值可为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及以上优化开关)

修改上述代码,将GetA的实现修改成:


A GetA()
{
    A o;
    return o;
}

在g++、vs2005+ Release中,上述代码也仅仅只会调用一次构造函数和析构函数 ,输出结果如下:

0x7ffe9d1edd0f construct

0x7ffe9d1edd0f destruct

g++加上-fno-elide-constructors选项关闭优化后,和上述结果一样

0x7ffc46947d4f construct

0x7ffc46947d7f copy construct

0x7ffc46947d4f destruct

0x7ffc46947d7e copy construct

0x7ffc46947d7f destruct

0x7ffc46947d7e destruct

但在vc6、vs2005以下、vs2005+ Debug中,没有进行NRVO优化,输出结果为:

18fec4 construct  // 在函数GetA中,调用无参构造函数A()构造出一个临时变量o

18ff44 copy construct  // 函数GetA return语句处,把临时变量o做为参数传入并调用拷贝构造函数A(const A& cp)将返回值ret构造出来

18fec4 destruct  // 函数GetA执行完return语句后,临时变量o生命周期结束,调用其析构函数~A()

18ff44 destruct // A a要离开作用域,生命周期结束,调用其析构函数~A()

下面用c++代码模拟一下vc6、vs2005以下、vs2005+ Debug上的行为:


#include <new>
A& GetA(void* p)
{
    A o;
    //由于p的内存是从外部传入的,函数返回后仍然有效,因此返回值可为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只优化掉了返回值到变量a的拷贝,命名局部变量o没有被优化掉,所以最后一共有2次构造和析构的调用

复制省略

典型情况是:调用构造函数进行值类型传参


void Func(A a) 
{
}

int main()
{
    {
        Func(A());
    }

    return 0;
}

在g++和vc6、vs中,上述代码仅仅只会调用一次构造函数和析构函数 ,输出结果如下:

0x7ffeb5148d0f construct

0x7ffeb5148d0f destruct

在g++中,加上-fno-elide-constructors选项关闭优化后,输出结果如下:

0x7ffc53c141ef construct   // 在main函数中,调用无参构造函数构造实参变量o

0x7ffc53c141ee copy construct // 调用Func函数后,将实参变量o做为参数传入并调用拷贝构造函数A(const A& cp)将形参变量a构造出来

0x7ffc53c141ee destruct // 函数Func执行完后,形参变量a生命周期结束,调用其析构函数~A()

0x7ffc53c141ef destruct // 返回main函数后,实参变量o要离开作用域,生命周期结束,调用其析构函数~A()

下面用c++代码模拟一下其优化行为:


void Func(const A& a) 
{
}

int main()
{
    {
        Func(A());
    }

    return 0;
}

优化失效的情况

开启g++优化,得到以下各种失效情况的输出结果:

(1)根据不同的条件分支,返回不同变量


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次缺省构造函数调用:用于构造a1、a2

注2:1次拷贝构造函数调用:用于拷贝构造返回值

注3:这儿仍然用右值引用优化掉了一次拷贝函数调用:返回值赋值给a

(2)返回参数变量

(3)返回全局变量

(4)返回复合数据类型中的成员变量

(5)返回值赋值给已构造好的变量(此时会调用operator==赋值运算符)

以上就是详解C++编译器优化技术的详细内容,更多关于C++编译器优化技术的资料请关注编程网其它相关文章!

--结束END--

本文标题: 详解C++编译器优化技术

本文链接: https://www.lsjlt.com/news/127700.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 详解C++编译器优化技术
    目录前言RVONRVO复制省略优化失效的情况前言 注1:vc6、vs没有提供编译选项来关闭该优化,无论是debug还是release都会进行RVO和复制省略优化 注2:vc6、vs2...
    99+
    2022-11-12
  • C++中编译优化问题的详解
    C++中编译优化问题的详解编写高效的C++代码是每个程序员都追求的目标,而编译优化就是其中一个重要的方面。正确理解和应用编译优化可以极大地提高程序的性能和效率。本文将从C++编译优化的基本原理、常见的优化技术和具体的代码示例入手,详细解析C...
    99+
    2023-10-22
    C++编译优化问题
  • C++中编译优化问题和解决方法的详解
    C++中编译优化问题和解决方法的详解摘要:C++编译器优化是提高程序性能的重要手段。然而,在实际开发中,我们经常会遇到一些与编译优化相关的问题,比如编译器错误优化、代码性能下降等。本文将针对这些问题进行详细的解析,并提供相应的解决方法,以期...
    99+
    2023-10-22
    问题解决方法 C++编译优化 详解编程关键词
  • Vue编译优化实现流程详解
    目录动态节点收集与补丁标志1.传统diff算法的问题2.Block和PatchFlags3.收集动态节点4.渲染器运行时支持5.Block树静态提升预字符化缓存内联事件处理函数v-o...
    99+
    2023-01-28
    Vue编译优化 Vue代码优化
  • C++编译器Clion的使用详解(总结)
    推荐教程 Clion2020.2.x最新激活版附安装教程(Mac Linux Windows) 最新clion2020激活附安装教程(亲测有效) Clion是由JetBrains公司...
    99+
    2022-11-12
  • 揭秘golang编译器:深入解析常见的编译器技术和应用
    Golang编译器大揭秘:详解常见的编译器技术与应用引言:随着计算机技术的不断发展,编译器在软件开发中的重要性日益突出。作为一门高级编程语言,Golang的编译器在保证代码执行效率的同时,也在提高开发效率上有许多优秀的表现。本文将深入探讨G...
    99+
    2023-12-29
    应用 golang编译器 编译器技术
  • 详解Java编译优化之循环展开和粗化锁
    目录循环展开和粗化锁分析Assembly日志禁止Loop unrolling循环展开和粗化锁 我们先来回顾一下什么是循环展开。 循环展开就是说,像下面的循环遍历的例子: for ...
    99+
    2022-11-12
  • C++中编译优化问题及解决方法概述
    C++中编译优化问题及解决方法概述引言:编译优化是在编译过程中对代码进行优化的一种技术。优化可以提高程序的执行效率、减少内存占用以及降低功耗。然而,虽然编译器在编译过程中会尽力优化代码,但在某些特定情况下,编译器可能无法进行有效的优化,从而...
    99+
    2023-10-22
    问题解决 C++编译优化 方法概述
  • C++中常见的编译优化问题解决方案
    C++中常见的编译优化问题解决方案摘要:在使用C++编写程序时,我们经常会遇到一些性能瓶颈,影响程序的运行效率。为了提高代码的执行效率,我们可以使用编译器进行优化。本文将介绍一些常见的编译优化问题及其解决方案,并给出具体的代码示例。一、循环...
    99+
    2023-10-22
    内联优化 (Inlining Optimization) 循环展开优化 (Loop Unrolling Optimiza
  • C#中如何使用编译器优化代码性能
    C#中如何使用编译器优化代码性能,需要具体代码示例引言:在软件开发中,代码性能是一个重要的考量因素。好的代码性能可以提升程序的运行速度,减少资源占用,并提供更好的用户体验。而在C#开发中,编译器提供了一些优化技术,可以帮助我们进一步提升代码...
    99+
    2023-10-22
    性能 编译器 优化
  • 优化 HTTP 传输:Python 重定向技术详解
    HTTP 重定向是一个常见的 Web 开发技术,它可以让用户在访问网站时自动跳转到另一个页面。在实际应用中,我们经常需要使用 Python 来实现 HTTP 重定向功能。本文将介绍 Python 重定向技术的实现原理和具体操作,帮助读者快...
    99+
    2023-11-06
    重定向 大数据 http
  • 如何理解Go编译器代码优化bug定位和修复
    这篇文章主要介绍“如何理解Go编译器代码优化bug定位和修复”,在日常操作中,相信很多人在如何理解Go编译器代码优化bug定位和修复问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解...
    99+
    2022-10-19
  • 深入了解golang编译器的发展历程和优化策略
    一文读懂golang编译器的演化历程与优化策略当谈到编程语言中的编译器时,很多人可能会想到C语言或Java,但在近些年里,一门名为Golang的编程语言越来越受到程序员的关注和喜爱。Golang是Google开发的一门静态类型、编译型的高级...
    99+
    2023-12-29
    策略 编译器 优化 Golang 演化
  • 阿里云架设网游服务器技术详解与优势分析
    随着互联网技术的发展,网络游戏已经成为人们日常生活中不可或缺的一部分。而在这种背景下,如何保证网络游戏的稳定运行,成为了游戏开发者和运维人员所关注的重要问题。而在这个过程中,云服务器的作用则显得尤为重要。本文将详细介绍阿里云架设网游服务器的...
    99+
    2023-12-18
    阿里 网游 详解
  • GO 编程中的算法优化策略,容器技术如何助力 Windows 平台?
    在 GO 编程中,算法优化策略是一项非常重要的工作。随着计算机的不断发展,算法优化已经成为了程序员必备的技能之一。在本文中,我们将探讨 GO 编程中的算法优化策略,以及如何借助容器技术助力 Windows 平台。 算法优化策略 在 GO 编...
    99+
    2023-09-13
    编程算法 容器 windows
  • 阿里云搭建Unturned服务器详解搭建步骤与优化技巧
    在众多的游戏服务器提供商中,阿里云无疑是一个佼佼者。其强大的服务器性能、丰富的服务类型以及优质的售后服务,都使得阿里云成为了许多游戏开发者和玩家的首选。本文将详细介绍如何使用阿里云搭建Unturned服务器,并提供一些优化技巧。 一、搭建U...
    99+
    2023-10-29
    阿里 详解 步骤
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作