趙靜,張寧寧
(中航工業(yè)北京長城計量測試技術(shù)研究所,北京100095)
在構(gòu)建自動化控制系統(tǒng)時,計算機軟件編程是使得自動控制系統(tǒng)在無人參與情況下按照預(yù)期程序進行工作的關(guān)鍵所在。在預(yù)定程序的實現(xiàn)中,軟件編程不僅要實現(xiàn)所需的任務(wù)要求,而且在運行效率、差錯管理、系統(tǒng)維護等方面要付出更多的精力。由于無人工參與,某些想象不到的小錯誤可能會引起軟件的崩潰,進而嚴重威脅整個控制系統(tǒng)。
隨著自動控制系統(tǒng)的不斷擴展,所需要實現(xiàn)的功能越來越多,系統(tǒng)越來越龐大,軟件編程越來越復(fù)雜,然而計算機的內(nèi)存資源是有限的,內(nèi)存管理的目的就是如何高效、快速的為任務(wù)分配內(nèi)存資源,并且在適當(dāng)?shù)臅r候釋放和回收資源,內(nèi)存管理技術(shù)在編程中越來越受到重視。一個內(nèi)存管理好的程序不僅可以提高工作效率,而且可以使系統(tǒng)更為穩(wěn)定的運行,內(nèi)存管理不好可能導(dǎo)致內(nèi)存泄露,甚至內(nèi)存耗盡而導(dǎo)致系統(tǒng)崩潰。
本文基于LabVIEW編程語言來介紹內(nèi)存管理,通過匯總LabVIEW的一些內(nèi)存管理技術(shù)以及一些編程技巧,以幫助LabVIEW編程者更好的實現(xiàn)自動控制系統(tǒng)的軟件編程。
自動控制系統(tǒng)一般包括控制器、被控對象以及執(zhí)行機構(gòu)??刂破骷从嬎銠C及其內(nèi)置板卡;被控對象即終端設(shè)備;執(zhí)行機構(gòu)即實現(xiàn)基本控制任務(wù)、數(shù)據(jù)采集任務(wù)等的硬件結(jié)構(gòu),如電機、電磁閥、數(shù)據(jù)采集儀等。圖1是一個簡單的自動控制系統(tǒng)的基本構(gòu)架。
圖1 自動控制系統(tǒng)框圖
系統(tǒng)中的控制部分往往需要用到計算機的各種硬件資源口:串口、網(wǎng)口、GPIB口等,或者需要多功能采集卡的多功能通道來進行控制,這些系統(tǒng)資源端口在進行軟件編程時要注意及時的分配和釋放,如果釋放不當(dāng),會導(dǎo)致資源口的無效占用,可能導(dǎo)致再次使用時打開失敗。
系統(tǒng)本身具有自檢功能,這是在整個程序控制中首先要進行的工作,之后又不再需要進行頻繁操作,這就涉及到了系統(tǒng)資源的合理分配問題,如何使不常用的功能最少的占用內(nèi)存資源,并能更好的提高運行效率。
在某些復(fù)雜系統(tǒng)中,數(shù)據(jù)量很大,占用的內(nèi)存資源也會很大,如何在編程中注意內(nèi)存資源的管理是提高數(shù)據(jù)處理量、提高運行效率的關(guān)鍵。
此外,系統(tǒng)還包括了實時采集數(shù)據(jù)、人機控制、報表操作等多個功能,合理的內(nèi)存管理機制可以提高計算機多任務(wù)處理中的內(nèi)存利用率,保證系統(tǒng)運行的穩(wěn)定性和提高系統(tǒng)的運行效率。
2.1.1 內(nèi)存使用的查看工具
在VI屬性面板中的“內(nèi)存使用”工具是用來查看VI內(nèi)存占用情況的。它顯示了一個VI內(nèi)存占用所包含的四個主要部分:前面板、框圖、代碼和數(shù)據(jù),以及四個部分的總和。通過這個工具,我們可以方便的查看VI所占用的內(nèi)存,更有針對性的進行優(yōu)化。
2.1.2 查看數(shù)據(jù)的內(nèi)存?zhèn)浞?/p>
通過本工具可以方便的找到產(chǎn)生內(nèi)存拷貝的數(shù)據(jù)節(jié)點,更便于進行程序的優(yōu)化設(shè)計,對某些不必要的內(nèi)存拷貝,要盡量避免。此外,工具選項下的性能分析有幾個查看工具,靈活運用這些工具可以更方便的進行內(nèi)存管理。
當(dāng)打開一個主VI時,主VI連同它所有子VI的代碼和數(shù)據(jù)段都會被調(diào)入內(nèi)存,但未打開的前面板和框圖并不會被調(diào)入內(nèi)存,只有當(dāng)主動查看VI的前面板或框圖時,才會被調(diào)用?;贚abVIEW的這種內(nèi)存管理特性,介紹幾個優(yōu)化LabVIEW程序的內(nèi)存管理方法。
2.2.1 子VI的使用
一個復(fù)雜的自動控制系統(tǒng)的程序往往需要實現(xiàn)多個功能,將每個功能模塊用單獨子VI實現(xiàn),雖然會增加額外的前面板和框圖空間,但并不增加額外的代碼和數(shù)據(jù)空間,因此也不會占用額外的內(nèi)存資源。使用子VI還可以方便LabVIEW在結(jié)束子VI運行時及時回收內(nèi)存資源,更進一步改善了內(nèi)存的使用效率。
2.2.2 動態(tài)調(diào)用子VI
自動控制系統(tǒng)中有些功能在程序運行過程中只需要執(zhí)行一次,例如:系統(tǒng)的自檢功能;有些功能在整個程序運行中需要不斷調(diào)用,例如:設(shè)備控制部分和數(shù)據(jù)采集部分。不常用的自檢功能采用動態(tài)調(diào)用VI方式,即只有在調(diào)用時該子VI時才加載到內(nèi)存中,運行完后在內(nèi)存中清除此VI;對常用功能采用普通調(diào)用方式,即系統(tǒng)在運行程序時就將此VI加載到內(nèi)存中,只有退出主程序時,該VI才從內(nèi)存中清除。動態(tài)調(diào)用程序框圖如圖2所示。
圖2 動態(tài)調(diào)用VI程序圖
合理利用兩種調(diào)用方式,可以提高內(nèi)存利用率,避免不常用VI長期占用內(nèi)存空間。
2.2.3 數(shù)據(jù)備份及緩存重用
自動控制系統(tǒng)中的數(shù)據(jù)處理部分,往往要涉及到大量的數(shù)據(jù)運算,有時要求把采集到的數(shù)據(jù)顯示成波形,LabVIEW程序主要是數(shù)據(jù)流驅(qū)動型的。數(shù)據(jù)傳遞到不同節(jié)點時往往需要復(fù)制一個副本。當(dāng)對大的數(shù)組進行運算時,內(nèi)存消耗很大,就是因為程序生成了過多的副本。
有些LabVIEW節(jié)點可以緩存重用,合理利用這些節(jié)點可以有效的提高內(nèi)存使用率,減少備份。
1)移位寄存器的使用
移位寄存器是內(nèi)存優(yōu)化的一個重要節(jié)點,其在循環(huán)結(jié)構(gòu)的兩端是強制使用同一塊內(nèi)存的。圖3是對實現(xiàn)同一功能的兩種LabVIEW節(jié)點的編程比較。
圖3 移位寄存器節(jié)點比較
經(jīng)過內(nèi)存查看工具發(fā)現(xiàn)第一種方式大概占用了3.4 M的內(nèi)存空間,第二種方式僅占用了1.2 M的內(nèi)存空間。
2)元素同址操作
元素同址節(jié)點是另外一種強制數(shù)據(jù)緩存重用內(nèi)存的一種方式。該節(jié)點用于數(shù)組的索引、替換,簇的綁定和解除以及任意元素的緩存重用,可以使更新數(shù)據(jù)或簇中元素時,不進行數(shù)據(jù)備份。圖4是同址操作結(jié)構(gòu)的程序框圖。
圖4 元素同址節(jié)點應(yīng)用
2.2.4 全局變量和局部變量的應(yīng)用
在自動控制系統(tǒng)的人機交互編程中往往會用到大量的界面操作,針對同一控件的讀寫操作往往出現(xiàn)在程序的不同位置。這時就會用到界面元素的屬性特點或者使用局部變量來實現(xiàn)操作。另外,在數(shù)據(jù)處理的編程部分中,有些復(fù)雜的算法往往需要順序結(jié)構(gòu)多步實現(xiàn),這時也會用到局部變量來進行參數(shù)的傳遞。圖5是兩種編程方式的比較。
圖5 局部變量使用比較
經(jīng)過測試發(fā)現(xiàn),第一種方式的運行時間是191 ms,占用內(nèi)存42.2 M;第二種方式的運行時間是159 ms,占用內(nèi)存9.0 M。
局部變量和全局變量都會涉及到數(shù)據(jù)的備份,對某些大型數(shù)組的操作會導(dǎo)致內(nèi)存的大量占用,可以利用以下方式避免局部變量的應(yīng)用。
錯誤簇的方式不僅能使數(shù)據(jù)的傳輸保持一定的順序,而且可以避免局部變量的使用。錯誤簇的例子如圖6所示。
全局變量除了有內(nèi)存?zhèn)浞莸谋撞≈?,還存在競爭的問題。在程序的任何地方都可以隨意更改全局變量的值,容易造成其值被莫名其妙更改,且不便于程序的調(diào)試。全局變量在編程中可以通過使用隊列或者通告、事件結(jié)構(gòu)等方式來盡量避免。
圖6 錯誤簇的妙用
2.2.5 防止內(nèi)存泄露
在控制系統(tǒng)的設(shè)備控制部分和數(shù)據(jù)采集部分以及文件I/O部分,會經(jīng)常用到設(shè)備端口的配置、采集卡任務(wù)的創(chuàng)建以及文件引用的創(chuàng)建。如果忘記關(guān)閉這些引用,就會導(dǎo)致內(nèi)存泄露,由于內(nèi)存泄漏是動態(tài)產(chǎn)生的,我們無法通過VI屬性面板來查看,但可以通過Windows自帶的任務(wù)管理工具來查看。也可以使用LabVIEW的Profile(Tools>>Advanced>>Profile VIs)工具來查看某個VI運行時內(nèi)存的分配情況。
圖7是控制儀器和文件打開和關(guān)閉引用的例子。
圖7 防止內(nèi)存泄露的程序框圖
2.2.6 減少數(shù)據(jù)備份
盡量使用占用資源較小的數(shù)據(jù)類型,例如使用16位整型數(shù)據(jù),而不是雙精度浮點數(shù);盡量要在循環(huán)內(nèi)進行大量數(shù)據(jù)的運算操作;合理利用內(nèi)聯(lián)VI。
以一套傳感器的壓力溫度性能檢測系統(tǒng)為例,對內(nèi)存管理進行實例分析。本系統(tǒng)的基本組成如圖9所示。
該系統(tǒng)是用于檢測傳感器在不同溫度、不同壓力情況下的輸出性能。主要實現(xiàn)的功能在圖10中列出。
圖9 壓力溫度試驗系統(tǒng)
圖10 軟件功能框圖
整個程序采用事件驅(qū)動機制,將事件響應(yīng)節(jié)點放在順序框圖中,第一步是對硬件各種引用的打開操作,并進行差錯管理,一旦有錯誤就關(guān)閉引用,以避免出現(xiàn)錯誤時導(dǎo)致引用無法關(guān)閉而引起內(nèi)存泄露。所有與主要功能無關(guān)的界面操作均在此步中實現(xiàn),以避免在進行主要功能時影響運行效率;順序的第二部分是主要功能的實現(xiàn),此部分全局變量主要用于存儲數(shù)值常量包括一些硬件的命令字符串,在自動控制循環(huán)中應(yīng)用移位寄存器來實現(xiàn)數(shù)據(jù)的傳輸,例如壓力控制部分,需要循環(huán)得到實際壓力值,并通過平均值判斷是否到達指定標準值,此時應(yīng)用移位寄存器而不是直接的數(shù)組累加方式來實現(xiàn)壓力值的平均值求取,溫度控制也類似;為了得到傳感器的性能分析,需要對采集到的大量數(shù)據(jù)進行數(shù)學(xué)計算,這時盡量應(yīng)用錯誤簇取代局部變量的應(yīng)用來實現(xiàn)計算的先后順序,且在數(shù)據(jù)運算時盡量保持運算中數(shù)值類型的一致性;順序的最后一步是對各種引用的正常關(guān)閉,以及文件的操作、界面元素的恢復(fù)等。
整個程序本著優(yōu)化內(nèi)存管理的思路,實現(xiàn)了要求的所有功能。
[1]李周華,嚴毅.軟件設(shè)計中的性能優(yōu)化與內(nèi)存管理[C]//廣西計算機學(xué)會——2004年學(xué)術(shù)年會論文集.2004.
[2]Jeffrey Richter.Windows核心編程 [M].北京:機械工業(yè)出版社,2000.
[3]魏海濤,姜昱明,李建武,等.內(nèi)存管理機制的高效實現(xiàn)研究[J].計算機工程與設(shè)計,2009(16):3708-3712.