• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            eryar

            PipeCAD - Plant Piping Design Software.
            RvmTranslator - Translate AVEVA RVM to OBJ, glTF, etc.
            posts - 603, comments - 590, trackbacks - 0, articles - 0

            C++ 應(yīng)用程序性能優(yōu)化

            Posted on 2016-07-31 13:44 eryar 閱讀(4918) 評(píng)論(4)  編輯 收藏 引用 所屬分類: 2.OpenCASCADE

            C++ 應(yīng)用程序性能優(yōu)化

            eryar@163.com

            1. Introduction

            對(duì)于幾何造型內(nèi)核OpenCASCADE,由于會(huì)涉及到大量的數(shù)值算法,如矩陣相關(guān)計(jì)算,微積分,Newton迭代法解方程,以及非線性優(yōu)化的一些算法,如BFGS,F(xiàn)RPR,PSO等等用于多元函數(shù)的極值求解,所以這些數(shù)值算法的性能直接影響系統(tǒng)的性能。軟件的性能優(yōu)化是計(jì)算機(jī)軟件開發(fā)過程中需要一直關(guān)注的重要因素,因此有必要學(xué)習(xí)下C++應(yīng)用程序性能優(yōu)化的方法。

            在網(wǎng)上尋找相關(guān)資料時(shí),發(fā)現(xiàn)這方面的資料也很少,最后發(fā)現(xiàn)一本由電子工業(yè)出版社出版的《C++應(yīng)用程序性能優(yōu)化方法》,從中可以學(xué)習(xí)下IBM的性能優(yōu)化方法。

            本文主要結(jié)合《C++性能優(yōu)化方法》并結(jié)合代碼實(shí)例來說明內(nèi)存優(yōu)化處理對(duì)程序性能的影響。看完本書,其實(shí)發(fā)現(xiàn)C++性能優(yōu)化方法主要還是依賴的計(jì)算機(jī)相關(guān)的基礎(chǔ)知識(shí),比如說計(jì)算機(jī)操作系統(tǒng),數(shù)據(jù)結(jié)構(gòu)與算法等等。

            2.Memory Optimize

            C++程序中的存儲(chǔ)空間可以分為靜態(tài)/全局存儲(chǔ)區(qū),棧區(qū)和堆區(qū)。靜態(tài)/全局存儲(chǔ)區(qū)和棧區(qū)的大小一般在程序編譯階段決定;而堆區(qū)則隨著程序的運(yùn)行而動(dòng)態(tài)變化,每一次程序運(yùn)行都會(huì)有不同的行為。這種動(dòng)態(tài)的內(nèi)存管理對(duì)于一個(gè)程序在運(yùn)行過程中占用的內(nèi)存大小及程序的性能有非常重要的影響。

            因?yàn)殪o態(tài)/全局存儲(chǔ)區(qū)在編譯時(shí)就已經(jīng)確定了,而棧區(qū)則是由操作系統(tǒng)在管理,這些都不勞程序員費(fèi)神。就是這個(gè)堆區(qū)是提供給程序員的自由舞臺(tái),可以任性發(fā)揮。堆區(qū)的存儲(chǔ)區(qū)域怎么玩呢?理解了這三個(gè)問題應(yīng)該就知道了:一是堆區(qū)數(shù)據(jù)怎么產(chǎn)生(從哪兒來)?二是堆區(qū)的數(shù)據(jù)怎么銷毀(到哪兒去)?堆區(qū)數(shù)據(jù)怎么訪問?由C++標(biāo)準(zhǔn)規(guī)定得知,C++實(shí)現(xiàn)通過全局的new和delete來提供動(dòng)態(tài)內(nèi)存的訪問和管理。而堆區(qū)數(shù)據(jù)的訪問就是通過指針了。當(dāng)使用new/delete來操作堆上的存儲(chǔ)區(qū)域時(shí),操作系統(tǒng)就要對(duì)堆的存儲(chǔ)區(qū)域進(jìn)行管理,所以這個(gè)管理工作就會(huì)對(duì)應(yīng)用程序的性能有影響。

            為了解決內(nèi)存泄露問題,即new之后不再使用時(shí)并沒有delete,OpenCASCADE中入了Handle智能指針的宏定義。Handle的使用也很簡(jiǎn)單,只需要將用Handle(Class)就可以了。

            利用默認(rèn)的內(nèi)存管理new/delete在堆上分配和釋放內(nèi)存會(huì)有一些額外的開銷。系統(tǒng)在接收到一定大小內(nèi)存請(qǐng)求時(shí),首先查找內(nèi)部維護(hù)的內(nèi)存空閑塊表,并且需要根據(jù)一定的算法(例如分配最先找到的不小于申請(qǐng)大小的內(nèi)存塊給請(qǐng)求者,或者分配最適于申請(qǐng)大小的內(nèi)存塊等)找到合適大小的內(nèi)存塊。如果該空閑內(nèi)存塊過大,還需要切割成已分配的部分和較小的空閑塊,然后系統(tǒng)更新內(nèi)存塊表,完成一次內(nèi)存分配。類似地,在釋放內(nèi)存時(shí),系統(tǒng)把釋放的內(nèi)存塊重新加入到空閑內(nèi)存塊表中。如果有可能的話,可以把相鄰的空閑塊合并成較大的空閑塊。

            默認(rèn)的內(nèi)存管理函數(shù)還考慮到多線程的應(yīng)用,需要在每次分配和釋放內(nèi)存時(shí)加鎖,同樣增加開銷。可見,如果應(yīng)用程序頻繁地在堆上分配格釋放內(nèi)存,則會(huì)導(dǎo)致性能的損失。并且會(huì)使系統(tǒng)中出現(xiàn)大量的內(nèi)存碎片,降低內(nèi)存的利用率。

            由此可見,在簡(jiǎn)單的new和delete背后,系統(tǒng)默默地為我們做了這么多的事,而做這些事都是要花時(shí)間的啊!雖然默認(rèn)的內(nèi)存管理算法也考慮了性能,但是考慮的是更通用的情況,為了應(yīng)付更復(fù)雜、更廣泛的情況,需要做更多額外工作。而對(duì)于具體的應(yīng)用程序來說,適合自身特定的內(nèi)存管理則可以獲得更好的性能,為此OpenCASCADE引入了自己的內(nèi)存管理機(jī)制,與內(nèi)存池概念類似。OCCT的內(nèi)存通過配置,可以使用沒的優(yōu)化技術(shù),或者不使用任何優(yōu)化直接使用系統(tǒng)的malloc和free。這些配置都是通過環(huán)境變量來實(shí)現(xiàn),其中打開和關(guān)閉內(nèi)存優(yōu)化的開關(guān)是環(huán)境變量:MMGT_OPT,這個(gè)默認(rèn)是0,即不使用任何優(yōu)化;設(shè)置成1就是使用;設(shè)置成2就是使用TBB的內(nèi)存優(yōu)化技術(shù)(這個(gè)的前提是第三方庫正確配置,如果沒有還是使用的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

            下面通過代碼來看看使用內(nèi)存管理的性能有什么變化。

            3.Code Example

            下面通過程序來看看使用這些技術(shù)對(duì)性能的影響:


            /*
            *    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;
            }

            如果直接運(yùn)行上面的代碼編譯的程序,得到的結(jié)果如下圖所示:

            wpsECE0.tmp

            由圖可知,當(dāng)使用Handle(智能指針)的時(shí)候,時(shí)間上影響不大,即使用Handle對(duì)性能影響基本上可以忽略,但是得到很多好處,主要的就是不用自己去delete了。使用Visual Studio的性能分析工具查看,結(jié)果也類似:

            wpsECF1.tmp

            時(shí)間的開銷也是集中在內(nèi)存的分配上面:

            wpsED02.tmp

            注意到上面的Allocate()是類Standard_MMgrRaw的,即是直接使用的系統(tǒng)的malloc和free來管理內(nèi)存。下面設(shè)置環(huán)境變量MMGT_OPT=1來使用OCCT的內(nèi)存優(yōu)化類看看對(duì)性能影響如何?

            wpsED03.tmp

            程序運(yùn)行的結(jié)果如下圖所示:

            wpsED13.tmp

            與沒有使用內(nèi)存優(yōu)化的時(shí)候0.1相比,使用了內(nèi)存優(yōu)化處理的要快40%左右。

            由下圖可以看出,性能熱點(diǎn)也是集中在內(nèi)存的分配上面:

            wpsED14.tmp

            注意現(xiàn)在內(nèi)存分配使用的是Standard_MMgrOpt類中的Allocate函數(shù):

            wpsED15.tmp

            總的來說,將環(huán)境變量MMGT_OPT設(shè)置成1來使用OCCT的內(nèi)存優(yōu)化算法,性能提升還是很明顯的。

            4.Conclusion

            當(dāng)程序規(guī)模越來越大,算法越來算復(fù)雜的時(shí)候,找到性能的瓶頸越麻煩一些。性能優(yōu)化第一步是測(cè)量,找到合適的測(cè)量工具。《C++應(yīng)用程序性能優(yōu)化》一書中提供的是IBM Rational Quantify,在網(wǎng)上搜了下還有Intel VTune Amplifier等,功能都很強(qiáng)大。在Windows中開發(fā)程序使用的Visual Studio自帶了性能分析功能,使用起來也比較方便。

            找到性能瓶頸,就要對(duì)其進(jìn)行分析原因,進(jìn)而修改程序,提高性能。這方面的方法論可以借鑒《C++應(yīng)用程序性能優(yōu)化》,從數(shù)據(jù)結(jié)構(gòu)、程序啟動(dòng)、內(nèi)存管理等方面來分析。摘出此書中程序性能優(yōu)化的流程圖:

            wpsED16.tmp

            5. References

            1.馮宏華,徐瑩,程遠(yuǎn),汪磊. C++應(yīng)用程序性能優(yōu)化. 電子工業(yè)出版社.

            2.Scott Meryers. Effective C++(評(píng)注版). 電子工業(yè)出版社. 2011

            3.OpenCASCADE Foundation Classes Document 7.0.0. 2016

            Feedback

            # re: C++ 應(yīng)用程序性能優(yōu)化  回復(fù)  更多評(píng)論   

            2016-08-01 20:44 by ViCross
            是否 應(yīng)該是 在C++的Release下測(cè)試 更合適

            # re: C++ 應(yīng)用程序性能優(yōu)化  回復(fù)  更多評(píng)論   

            2016-08-01 20:57 by eryar
            @ViCross
            是的,debug和release還是有些區(qū)別

            # re: C++ 應(yīng)用程序性能優(yōu)化  回復(fù)  更多評(píng)論   

            2016-08-02 12:05 by 趙先生
            您好,我是某軟件公司的HR,對(duì)您提到的三維相關(guān)技術(shù)感興趣,請(qǐng)查閱您的郵箱: eryar(at)163.com,希望與您取得聯(lián)系

            # re: C++ 應(yīng)用程序性能優(yōu)化  回復(fù)  更多評(píng)論   

            2016-08-02 13:57 by eryar
            @趙先生
            Hi 趙先生,

            您好!

            感謝關(guān)注,郵件已經(jīng)回復(fù),請(qǐng)查收。

            Best Regards,
            Shing Liu
            国产免费久久久久久无码| 综合网日日天干夜夜久久| 国产精品乱码久久久久久软件| 国产精品一久久香蕉产线看| 国产色综合久久无码有码| 久久一本综合| 精品国产一区二区三区久久蜜臀| 波多野结衣中文字幕久久| 亚洲熟妇无码另类久久久| 久久久久亚洲AV无码观看| 久久久久亚洲AV无码专区桃色| 久久中文娱乐网| 久久无码av三级| 欧美精品一本久久男人的天堂| 国产精品对白刺激久久久| 欧美牲交A欧牲交aⅴ久久| 久久精品卫校国产小美女| 久久久久久久波多野结衣高潮| 青青草原综合久久大伊人| 蜜桃麻豆WWW久久囤产精品| 亚洲国产高清精品线久久| 无码人妻少妇久久中文字幕| 久久久WWW免费人成精品| 精品久久久久久国产三级| 无码8090精品久久一区| 久久无码AV一区二区三区| 精品国产乱码久久久久软件| 午夜天堂av天堂久久久| 狠狠色丁香久久婷婷综合五月| 精品久久久久久无码专区| 久久精品一区二区三区不卡| 久久精品一区二区| 欧美性猛交xxxx免费看久久久| 欧美性大战久久久久久| 伊人久久综合无码成人网 | 日本加勒比久久精品| 久久精品中文字幕大胸| 久久久噜噜噜www成人网| 中文字幕成人精品久久不卡| 性做久久久久久免费观看| 欧美精品久久久久久久自慰|