大量數(shù)據(jù)的內(nèi)存管理
LabVIEW自動處理內(nèi)存分配。因為該過程是自動的,LabVIEW在處理數(shù)據(jù)時必須注意數(shù)據(jù)的安全性。這就意味著LabVIEW需時常備份數(shù)據(jù)。如程序需處理大量數(shù)據(jù),大量的數(shù)據(jù)副本可能會導(dǎo)致內(nèi)存溢出錯誤。使用下列規(guī)范避免內(nèi)存問題,優(yōu)化程序以處理大量數(shù)據(jù)。注:也可使用記錄性能和內(nèi)存信息窗口,獲取和顯示VI執(zhí)行事件和內(nèi)存使用的數(shù)據(jù)。使用該窗口確定引發(fā)內(nèi)存問題的VI。減少大量數(shù)據(jù)的數(shù)據(jù)副本
LabVIEW是一種數(shù)據(jù)流語言,VI需要更多數(shù)據(jù)時(例如,數(shù)據(jù)連線分出兩條支路),LabVIEW會創(chuàng)建數(shù)據(jù)副本。大多數(shù)情況下LabVIEW能檢測是否需要創(chuàng)建一個新的副本,當(dāng)不確定是否需要數(shù)據(jù)副本時,LabVIEW仍然會創(chuàng)建新的數(shù)據(jù)副本。
使用顯示緩沖區(qū)分配窗口確定LabVIEW分配內(nèi)存的位置。該窗口確定LabVIEW用于存放數(shù)據(jù)副本的數(shù)據(jù)緩沖區(qū)。
請按照下列規(guī)范編寫程序,以減少LabVIEW創(chuàng)建的數(shù)據(jù)副本:
注:下列技巧中有些與良好的LabVIEW編程慣例不一致,這些技巧只在處理海量數(shù)據(jù)時使用。使用占用資源較小的數(shù)據(jù)類型。例如,使用16位整型數(shù)據(jù),而不是雙精度浮點數(shù)。使用簡單數(shù)組。當(dāng)從波形或動態(tài)數(shù)據(jù)提取數(shù)據(jù)數(shù)組時,LabVIEW會為數(shù)據(jù)建立額外副本。創(chuàng)建大程序框圖。調(diào)用子VI時,LabVIEW會創(chuàng)建數(shù)據(jù)副本。數(shù)據(jù)流經(jīng)子VI時,請確保所有程序框圖接線端均在條件結(jié)構(gòu)或循環(huán)之外。如接線端在條件結(jié)構(gòu)或循環(huán)中,LabVIEW將會產(chǎn)生越來越多的數(shù)據(jù)副本。如請不要將數(shù)據(jù)連接至循環(huán)內(nèi)。如要將數(shù)據(jù)連入循環(huán),可使用移位寄存器。LabVIEW只在第一次循環(huán)時復(fù)制一個數(shù)據(jù)副本。如使用隧道,每次循環(huán)時,LabVIEW都會創(chuàng)建數(shù)據(jù)副本。如有可能,使用必須連接的輸入。產(chǎn)生默認值時,LabVIEW將會創(chuàng)建數(shù)據(jù)副本。使用元素同址操作結(jié)構(gòu),而不是平鋪式順序結(jié)構(gòu)。提示:較新版本的LabVIEW比早期版本自動復(fù)制更多數(shù)據(jù)副本。版本越新,LabVIEW處理大量數(shù)據(jù)的功能就越好。傳輸大量數(shù)據(jù)如不能避免創(chuàng)建大量數(shù)據(jù)副本,可減少每個副本的大小。傳輸時,將大量數(shù)據(jù)分為若干部分,即數(shù)據(jù)塊策略。數(shù)據(jù)分塊時,LabVIEW創(chuàng)建的副本對內(nèi)存使用沒有負面影響。但是,這些副本對數(shù)據(jù)吞吐率還是有負面影響,所以,仍建議最小化這些副本。下例證明了這個概念。
需復(fù)制512 MB數(shù)據(jù)至磁盤。一次調(diào)用就可獲取所有數(shù)據(jù)并將數(shù)據(jù)保存至磁盤。但是,即時將數(shù)據(jù)副本減少為1,仍需傳輸原始數(shù)據(jù)和一個數(shù)據(jù)副本。這意味著要向LabVIEW要求1 GB的內(nèi)存。更好的方法是建立一個循環(huán),一次獲取500 KB的數(shù)據(jù)并流盤。內(nèi)存占用減少為1 MB,500 KB用于原始數(shù)據(jù),500 KB用于數(shù)據(jù)副本,這在大多數(shù)計算機的內(nèi)存容量之內(nèi)。
優(yōu)點是節(jié)省了LabVIEW分配大量內(nèi)存所需的海量時間。在多數(shù)計算機上,250 MB數(shù)據(jù)的流盤時間不超過15秒。如按照其它方法,LabVIEW分配1 GB RAM的時間很可能超過15秒。
如將大量數(shù)據(jù)流盤或存儲在冗余磁盤陣列(RAID)中,也可不通過緩沖區(qū)傳輸數(shù)據(jù),以減少數(shù)據(jù)副本,加快數(shù)據(jù)傳輸。如要禁用緩沖區(qū),將TRUE值連接至打開/創(chuàng)建/替換文件函數(shù)的禁用緩存輸入端。
顯示大量數(shù)據(jù)在許多交互式應(yīng)用程序中,唯一對數(shù)據(jù)進行的操作是顯示數(shù)據(jù)。顯示500萬個數(shù)據(jù)點超出了大多數(shù)顯示器的顯示能力。LabVIEW圖片的寬度一般在300-1000像素。500萬個點超過了波形圖實際顯示點數(shù)三個數(shù)量級。所以,需大量減少數(shù)據(jù)點。
例如,在圖形上看到精確至像素的大量數(shù)據(jù)。如一個500萬點緩沖區(qū)中有一個突波,繪制出的圖形應(yīng)該是一條水平線,上有一個一像素的突波。如果數(shù)據(jù)是一個正弦波,其周期數(shù)大于屏幕的像素寬度。圖形應(yīng)該是一個不間斷的頻帶,且無混疊。最大值最小值截取算法可解決上述兩個問題。
最大值最小值截取算法是在每個截取區(qū)間內(nèi)給出一個最大值和一個最小值,以截取部分數(shù)據(jù)。簡單截取使用每個截取區(qū)間的第一個數(shù)據(jù)點作為截取區(qū)間的數(shù)據(jù)點。簡單截取將會導(dǎo)致混疊,所以只能在時間緊迫,精度相對不重要的情況下使用該算法。
使用最大值最小值截取算法的第一步是確定圖形的像素寬度。使用圖形的繪圖區(qū):大小:寬度屬性,找到該項。每個像素寬度至少需兩個截取區(qū)間。將像素寬度乘以2,獲得區(qū)間數(shù)量,然后將數(shù)據(jù)除以區(qū)間數(shù)量,從而降低算法誤差。將數(shù)據(jù)長度除以這個數(shù),向最近數(shù)取整。得到的是截取的數(shù)據(jù)塊大小。對于每個數(shù)據(jù)塊,找到最大和最小點,并將其按照在數(shù)據(jù)集合中的順序排列。不必擔(dān)心最后一個數(shù)據(jù)塊的數(shù)據(jù)點比其它數(shù)據(jù)塊的少。問題在于小于像素寬度,在屏幕上不可見。將所有最大值和最小值數(shù)據(jù)連接起來,然后繪制這些數(shù)據(jù)。屏幕上每個像素寬度上有四個點。這樣,即使有一個像素寬度的突波,周圍的像素也不會受影響。最大值最小值截取法保證了永遠可以看到數(shù)據(jù)的峰值,顯示高頻率正弦波產(chǎn)生的不間斷頻帶。繪制到圖形的數(shù)據(jù)較少,繪制的速度就更快。
在下圖中,如使用最大值最小值截取算法處理左邊的數(shù)據(jù),LabVIEW將生成右邊的圖表。
存儲大量數(shù)據(jù)使用隊列或數(shù)據(jù)值引用在內(nèi)存中存儲大量數(shù)據(jù),而無需占用大量內(nèi)存。使用包含數(shù)據(jù)的單個元素創(chuàng)建一個隊列。要訪問數(shù)據(jù)時,可拆散隊列。這使程序的其它部分不能同步訪問某個數(shù)據(jù)。對數(shù)據(jù)操作完成后,將元素重新排入隊列。要傳遞的唯一對象是隊列的引用。傳遞隊列時,LabVIEW不創(chuàng)建額外的數(shù)據(jù)副本。給隊列命名后,可在任何時候使用獲取隊列函數(shù)獲取隊列引用。創(chuàng)建多個數(shù)據(jù)對象與創(chuàng)建多個隊列一樣容易。
還可使用數(shù)據(jù)值引用存儲數(shù)據(jù),不創(chuàng)建額外數(shù)據(jù)備份。數(shù)據(jù)值引用比隊列速度更快,但是沒有超時選項??蔀閿?shù)據(jù)創(chuàng)建引用并傳遞引用,而不是傳遞數(shù)據(jù)至隊列。如要對數(shù)據(jù)進行操作,可使用元素同址操作結(jié)構(gòu)。數(shù)據(jù)值引用寫入/讀取元素邊框節(jié)點接受數(shù)據(jù)值引用輸入,用戶可在元素同址操作結(jié)構(gòu)中操作數(shù)據(jù)并替換原內(nèi)存中的數(shù)據(jù)。
注:可在類屬性對話框的繼承頁上設(shè)置只有LabVIEW類的成員VI才可創(chuàng)建類的數(shù)據(jù)值引用。也可使用功能全局變量在內(nèi)存中存儲大量數(shù)據(jù)。使用功能性全局變量,LabVIEW將在數(shù)據(jù)塊中保存和訪問數(shù)據(jù)。這樣,不需大量內(nèi)存就可以傳輸數(shù)據(jù)。未初始化的移位寄存器可用來保存數(shù)據(jù)。使用數(shù)組函數(shù)讀取、寫入和重新調(diào)整數(shù)據(jù)。數(shù)組函數(shù)按順序排列數(shù)據(jù),不會創(chuàng)建數(shù)據(jù)副本。該方法通常比隊列方法慢。