C++ 应用程序性能优化
C++ 应用程序性能优化
1. Introduction
对于几何造型内核OpenCASCADE,由于会涉及到大量的数值算法,如矩阵相关计算,微积分,Newton迭代法解方程,以及非线性优化的一些算法,如BFGS,FRPR,PSO等等用于多元函数的极值求解,所以这些数值算法的性能直接影响系统的性能。软件的性能优化是计算机软件开发过程中需要一直关注的重要因素,因此有必要学习下C++应用程序性能优化的方法。
在网上寻找相关资料时,发现这方面的资料也很少,最后发现一本由电子工业出版社出版的《C++应用程序性能优化方法》,从中可以学习下IBM的性能优化方法。
本文主要结合《C++性能优化方法》并结合代码实例来说明内存优化处理对程序性能的影响。看完本书,其实发现C++性能优化方法主要还是依赖的计算机相关的基础知识,比如说计算机操作系统,数据结构与算法等等。
2.Memory Optimize
C++程序中的存储空间可以分为静态/全局存储区,栈区和堆区。静态/全局存储区和栈区的大小一般在程序编译阶段决定;而堆区则随着程序的运行而动态变化,每一次程序运行都会有不同的行为。这种动态的内存管理对于一个程序在运行过程中占用的内存大小及程序的性能有非常重要的影响。
因为静态/全局存储区在编译时就已经确定了,而栈区则是由操作系统在管理,这些都不劳程序员费神。就是这个堆区是提供给程序员的自由舞台,可以任性发挥。堆区的存储区域怎么玩呢?理解了这三个问题应该就知道了:一是堆区数据怎么产生(从哪儿来)?二是堆区的数据怎么销毁(到哪儿去)?堆区数据怎么访问?由C++标准规定得知,C++实现通过全局的new和delete来提供动态内存的访问和管理。而堆区数据的访问就是通过指针了。当使用new/delete来操作堆上的存储区域时,操作系统就要对堆的存储区域进行管理,所以这个管理工作就会对应用程序的性能有影响。
为了解决内存泄露问题,即new之后不再使用时并没有delete,OpenCASCADE中入了Handle智能指针的宏定义。Handle的使用也很简单,只需要将用Handle(Class)就可以了。
利用默认的内存管理new/delete在堆上分配和释放内存会有一些额外的开销。系统在接收到一定大小内存请求时,首先查找内部维护的内存空闲块表,并且需要根据一定的算法(例如分配最先找到的不小于申请大小的内存块给请求者,或者分配最适于申请大小的内存块等)找到合适大小的内存块。如果该空闲内存块过大,还需要切割成已分配的部分和较小的空闲块,然后系统更新内存块表,完成一次内存分配。类似地,在释放内存时,系统把释放的内存块重新加入到空闲内存块表中。如果有可能的话,可以把相邻的空闲块合并成较大的空闲块。
默认的内存管理函数还考虑到多线程的应用,需要在每次分配和释放内存时加锁,同样增加开销。可见,如果应用程序频繁地在堆上分配格释放内存,则会导致性能的损失。并且会使系统中出现大量的内存碎片,降低内存的利用率。
由此可见,在简单的new和delete背后,系统默默地为我们做了这么多的事,而做这些事都是要花时间的啊!虽然默认的内存管理算法也考虑了性能,但是考虑的是更通用的情况,为了应付更复杂、更广泛的情况,需要做更多额外工作。而对于具体的应用程序来说,适合自身特定的内存管理则可以获得更好的性能,为此OpenCASCADE引入了自己的内存管理机制,与内存池概念类似。OCCT的内存通过配置,可以使用没的优化技术,或者不使用任何优化直接使用系统的malloc和free。这些配置都是通过环境变量来实现,其中打开和关闭内存优化的开关是环境变量:MMGT_OPT,这个默认是0,即不使用任何优化;设置成1就是使用;设置成2就是使用TBB的内存优化技术(这个的前提是第三方库正确配置,如果没有还是使用的malloc和free;
// paralleling with Intel TBB
#ifdef HAVE_TBB
#include <tbb/scalable_allocator.h>
using namespace tbb;
#else
#define scalable_malloc malloc
#define scalable_calloc calloc
#define scalable_realloc realloc
#define scalable_free free
#endif
下面通过代码来看看使用内存管理的性能有什么变化。
3.Code Example
下面通过程序来看看使用这些技术对性能的影响:
/*
* Copyright (c) 2016 Shing Liu All Rights Reserved.
*
* File : main.cpp
* Author : Shing Liu(eryar@163.com)
* Date : 2016-07-31 11:54
* Version : OpenCASCADE7.0.0
*
* Description : Test OCCT Memory Manager and Handle(smart pointer).
*/ #include <OSD_Timer.hxx> #include <Poly.hxx>
#include <Poly_Triangulation.hxx> #pragma comment(lib, "TKernel.lib")
#pragma comment(lib, "TKMath.lib") /*
*@brief test memory without Handle(smart pointer) management.
*
*/
void testMemory(Standard_Integer theCount)
{
OSD_Timer aTimer;
aTimer.Start(); for (Standard_Integer i = ; i < theCount; i++)
{
Poly_Triangulation* aTriangulation = new Poly_Triangulation(, , Standard_False); delete aTriangulation;
} aTimer.Stop();
aTimer.Show();
} /*
*@brief test memory with Handle(smart pointer) management.
*
*/
void testHandle(Standard_Integer theCount)
{
OSD_Timer aTimer;
aTimer.Start(); for (Standard_Integer i = ; i < theCount; i++)
{
Handle(Poly_Triangulation) aTriangulation = new Poly_Triangulation(, , Standard_False);
} aTimer.Stop();
aTimer.Show();
} /*
* @brief set environment variable MMGT_OPT=0 to use malloc/free directly;
* set environment varialbe MMGT_OPT=1 to use OCCT memory optimization technique;
* set environment variable MMGT_OPT=2 to use paralleling with Interl TBB;
*/
int main(int argc, char* argv[])
{
int aCount = ; std::cout << "\ntest pointer without handle" << std::endl;
testMemory(aCount); std::cout << "\ntest pointer with handle" << std::endl;
testHandle(aCount); return ;
}
如果直接运行上面的代码编译的程序,得到的结果如下图所示:
![]()
由图可知,当使用Handle(智能指针)的时候,时间上影响不大,即使用Handle对性能影响基本上可以忽略,但是得到很多好处,主要的就是不用自己去delete了。使用Visual Studio的性能分析工具查看,结果也类似:
![]()
时间的开销也是集中在内存的分配上面:
![]()
注意到上面的Allocate()是类Standard_MMgrRaw的,即是直接使用的系统的malloc和free来管理内存。下面设置环境变量MMGT_OPT=1来使用OCCT的内存优化类看看对性能影响如何?
![]()
程序运行的结果如下图所示:
![]()
与没有使用内存优化的时候0.1相比,使用了内存优化处理的要快40%左右。
由下图可以看出,性能热点也是集中在内存的分配上面:
![]()
注意现在内存分配使用的是Standard_MMgrOpt类中的Allocate函数:
![]()
总的来说,将环境变量MMGT_OPT设置成1来使用OCCT的内存优化算法,性能提升还是很明显的。
4.Conclusion
当程序规模越来越大,算法越来算复杂的时候,找到性能的瓶颈越麻烦一些。性能优化第一步是测量,找到合适的测量工具。《C++应用程序性能优化》一书中提供的是IBM Rational Quantify,在网上搜了下还有Intel VTune Amplifier等,功能都很强大。在Windows中开发程序使用的Visual Studio自带了性能分析功能,使用起来也比较方便。
找到性能瓶颈,就要对其进行分析原因,进而修改程序,提高性能。这方面的方法论可以借鉴《C++应用程序性能优化》,从数据结构、程序启动、内存管理等方面来分析。摘出此书中程序性能优化的流程图:
![]()
5. References
1.冯宏华,徐莹,程远,汪磊. C++应用程序性能优化. 电子工业出版社.
2.Scott Meryers. Effective C++(评注版). 电子工业出版社. 2011
3.OpenCASCADE Foundation Classes Document 7.0.0. 2016
PDF Version: C++应用程序性能优化
C++ 应用程序性能优化的更多相关文章
- Java程序性能优化技巧
Java程序性能优化技巧 多线程.集合.网络编程.内存优化.缓冲..spring.设计模式.软件工程.编程思想 1.生成对象时,合理分配空间和大小new ArrayList(100); 2.优化for ...
- 《Java程序性能优化:让你的Java程序更快、更稳定》
Java程序性能优化:让你的Java程序更快.更稳定, 卓越网更便宜,不错的书吧
- [JAVA] java程序性能优化
一.避免在循环条件中使用复杂表达式 在不做编译优化的情况下,在循环中,循环条件会被反复计算,如果不使用复杂表达式,而使循环条件值不变的话,程序将会运行的更快. 例子: import java.util ...
- iOS程序性能优化
iOS程序性能优化 一.初级 使用ARC进行内存管理 在iOS5发布的ARC,它解决了最常见的内存泄露问题.但是值得注意的是,ARC并不能避免所有的内存泄露.使用ARC之后,工程中可能还会有内存泄露, ...
- [python]用profile协助程序性能优化
转自:http://blog.csdn.net/gzlaiyonghao/article/details/1483728 本文最初发表于恋花蝶的博客http://blog.csdn.net/lanph ...
- iOS 程序性能优化
前言 转载自:http://www.samirchen.com/ios-performance-optimization/ 程序性能优化不应该是一件放在功能完成之后的事,对性能的概念应该从我们一开始写 ...
- 微信小程序性能优化技巧
摘要: 如果小程序不够快,还要它干嘛? 原文:微信小程序性能优化方案--让你的小程序如此丝滑 作者:杜俊成要好好学习 Fundebug经授权转载,版权归原作者所有. 微信小程序如果想要优化性能,有关键 ...
- [转]C#程序性能优化
C#程序性能优化 1.显式注册的EvenHandler要显式注销以避免内存泄漏 将一个成员方法注册到某个对象的事件会造成后者持有前者的引用.在事件注销之前,前者不会被垃圾回收. private v ...
- [深入浅出Cocoa]iOS程序性能优化
本文转载至 http://blog.csdn.net/kesalin/article/details/8762032 [深入浅出Cocoa]iOS程序性能优化 罗朝辉 (http://blog.csd ...
随机推荐
- 最近帮客户实施的基于SQL Server AlwaysOn跨机房切换项目
最近帮客户实施的基于SQL Server AlwaysOn跨机房切换项目 最近一个来自重庆的客户找到走起君,客户的业务是做移动互联网支付,是微信支付收单渠道合作伙伴,数据库里存储的是支付流水和交易流水 ...
- js-静态、原型、实例属性
本篇来说一下js中的属性: 1.静态属性 2.原型属性 3.实例属性 静态属性: function klass(){} var obj=new klass(); klass.count=0; klas ...
- DDD 领域驱动设计-看我如何应对业务需求变化,愚蠢的应对?
写在前面 阅读目录: 具体业务场景 业务需求变化 "愚蠢"的应对 消息列表实现 消息详情页实现 消息发送.回复.销毁等实现 回到原点的一些思考 业务需求变化,领域模型变化了吗? 对 ...
- nodejs进阶(5)—接收请求参数
1. get请求参数接收 我们简单举一个需要接收参数的例子 如果有个查找功能,查找关键词需要从url里接收,http://localhost:8000/search?keyword=地球.通过前面的进 ...
- Matlab slice方法和包络法绘制三维立体图
前言:在地球物理勘探,流体空间分布等多种场景中,定位空间点P(x,y,x)的物理属性值Q,并绘制三维空间分布图,对我们洞察空间场景有十分重要的意义. 1. 三维立体图的基本要件: 全空间网格化 网格节 ...
- Tesseract-OCR字符识别简介
OCR(Optical Character Recognition):光学字符识别,是指对图片文件中的文字进行分析识别,获取的过程.Tesseract:开源的OCR识别引擎,初期Tesseract引擎 ...
- Spring的数据库开发
Spring JDBC框架操作mysql数据库 Spring中的JDBC为我们省去连接和关闭数据库的代码,我们着重关注对数据库的操作.Sprin ...
- css选择器
常用css选择器,希望对大家有所帮助,不喜勿喷. 1.*:通用选择器 * { margin: 0; padding: 0; } 选择页面上的全部元素,通常用于清除浏览器默认样式,不推荐使用. 2.#i ...
- 满堂红CIO邓劲翔:房屋中介突围
人脸识别.客户关系管理进度监控.业务流程实时监控.网站访问人数及流量实时监控等实际企业应用场景淋漓尽致.羽羽如生的以大屏幕上图表形式展现在人们面前,如果你不去继续询问,你不会知道这是一家才刚刚在房地产 ...
- IOS之Objective-C学习 ARC下的单例模式
单例模式是我常用的一种设计模式,最常见的用途就是用来保存数据并且传递数据.这都归功于单例模式的特性,首先就让我为大家简单介绍一下单例模式的特性. 单例模式的三大特性: 1.某个类只能有一个实例: 2. ...