eryar@163.comhtml
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)就能夠了。post
利用默認的內存管理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 = 0; i < theCount; i++) { Poly_Triangulation* aTriangulation = new Poly_Triangulation(10, 5, 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 = 0; i < theCount; i++) { Handle(Poly_Triangulation) aTriangulation = new Poly_Triangulation(10, 5, 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 = 100000; std::cout << "\ntest pointer without handle" << std::endl; testMemory(aCount); std::cout << "\ntest pointer with handle" << std::endl; testHandle(aCount); return 0; }
若是直接運行上面的代碼編譯的程序,獲得的結果以下圖所示:
由圖可知,當使用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++應用程序性能優化