labview深入探索------類型轉(zhuǎn)換、數(shù)組字符串與內(nèi)存管理
同其它高級語言一樣,也擁有基本的程序結(jié)構(gòu),比如,順序結(jié)構(gòu)、條件結(jié)構(gòu),循環(huán)結(jié)構(gòu)等。也擁有一些自己獨(dú)特的程序結(jié)構(gòu),如隊(duì)列、通告、信號、集合等等。
無論是數(shù)據(jù)類型還是程序結(jié)構(gòu),都是和內(nèi)存的使用緊密地結(jié)合在一起的,所以深入地了解數(shù)據(jù)類型和類型之間的轉(zhuǎn)換以及結(jié)構(gòu)在內(nèi)存中的存儲形式是非常重要的。
LABVIEW 中涉及到數(shù)據(jù)類型轉(zhuǎn)換時(shí),會引起內(nèi)存復(fù)制操作。大的數(shù)據(jù)類型結(jié)構(gòu)比如數(shù)組,字符串和簇在內(nèi)存中實(shí)際占的空間比我們預(yù)想的要大,因?yàn)長ABVIEW同時(shí)在內(nèi)存中也增加了很多必要的信息,正如我們在類型描述符中談到的。使用局部變量和全局變量也要引起內(nèi)存的復(fù)制操作,但是,恰當(dāng)?shù)木幊谭绞娇梢员苊膺@個(gè)問題。
(一)類型轉(zhuǎn)換是如何使用內(nèi)存的
類型轉(zhuǎn)換會產(chǎn)生兩個(gè)問題:增加了類型轉(zhuǎn)換時(shí)間 需要開辟新的BUFFER,增大了內(nèi)存空間的使用。
有些類型轉(zhuǎn)換是必要的,但是更多的情況下是我們編程時(shí)不注意造成的,對于人為發(fā)生的類型轉(zhuǎn)換要極力避免。
LV是圖形化編程方式,連線的顏色和線型代表了不同的數(shù)據(jù)類型,同時(shí)在轉(zhuǎn)換處還會有一個(gè)強(qiáng)制轉(zhuǎn)換點(diǎn),一般是黑色或者紅色,我們很容易看到在那里發(fā)生了隱含的類型轉(zhuǎn)換。
上面三個(gè)都是要完成+1操作,由于+節(jié)點(diǎn)雖然是多態(tài)的,可以適應(yīng)各種數(shù)據(jù)類型,但是默認(rèn)是DOUBLE型的,由于我先生成了常量1,黃色,導(dǎo)致U32在+節(jié)點(diǎn)處發(fā)生的類型轉(zhuǎn)換,最后輸出的是DOUBLE類型。而第二個(gè)我是先連接的U32,后自動(dòng)生成的常量1,LABVIEW自動(dòng)產(chǎn)生的U32常量而不是 DOUBLE,第三個(gè)直接調(diào)用+1節(jié)點(diǎn),所以不會發(fā)生類型轉(zhuǎn)換。所以編程風(fēng)格是非常重要
上面的圖中,因?yàn)镾UBVI需要的是DOUBLE類型的數(shù)組,而輸入數(shù)組是I16的,所以產(chǎn)生了一個(gè)強(qiáng)制轉(zhuǎn)換點(diǎn),因此,會產(chǎn)生同I16SIZE相同的額外的DOUBLE數(shù)組。
對于SIZE非常大的數(shù)組,不恰當(dāng)?shù)念愋娃D(zhuǎn)換耗費(fèi)的內(nèi)存是驚人的,看下面的圖
上圖第一個(gè)框圖,循環(huán)產(chǎn)生10000*64=80K的數(shù)組,因?yàn)闆]有類型轉(zhuǎn)換,有效地內(nèi)存重用,數(shù)據(jù)流上的執(zhí)行數(shù)據(jù)是80K,前面板數(shù)組指示器的操作數(shù)據(jù)是80K,總計(jì)160K
看看上圖中第二個(gè)框圖,他用了驚人的400K,不過是乘以一個(gè)擴(kuò)展精度的標(biāo)量,形成一個(gè)擴(kuò)展精度的數(shù)組,然后右重新強(qiáng)制轉(zhuǎn)換成DOUBLE數(shù)組??匆幌率侨绾萎a(chǎn)生的。
---循環(huán)80K
---強(qiáng)制轉(zhuǎn)換乘法后,數(shù)據(jù)流上的執(zhí)行數(shù)據(jù)是160K
---強(qiáng)制轉(zhuǎn)換成DOUBLE數(shù)組,生成另外的80K執(zhí)行數(shù)據(jù)
---數(shù)組指示器 80K操作數(shù)據(jù)
總計(jì):80K+160K+80K+80K=400K
可以看出中間乘法端子出現(xiàn)的EXT是毫無意義的,不經(jīng)意間,額外的240K內(nèi)存被耗費(fèi)掉了。
所以在數(shù)據(jù)流中如果數(shù)據(jù)類型不變,我們將節(jié)省240K的內(nèi)存,一個(gè)重要的原則就是:
盡量始終在數(shù)據(jù)流中保持同一種數(shù)據(jù)類型
上圖中,EXAMPEL1和EXAMPLE2是基本相當(dāng)?shù)?,一個(gè)是隱含的強(qiáng)制轉(zhuǎn)換點(diǎn),一個(gè)是用顯式的SGL--》DOUBLE轉(zhuǎn)換節(jié)點(diǎn),
它們用的內(nèi)存是完全相同的,但性能稍微有些差異,隱含轉(zhuǎn)換速度稍微快了一點(diǎn),并且節(jié)省的框圖的空間,比較方便。
而EXAMPE 3和EXAMPLE 4則是完全不同的,EXAPLE 3發(fā)生了二次隱含強(qiáng)制轉(zhuǎn)換,而EXAPLE 4只有一次顯式轉(zhuǎn)換。節(jié)省了內(nèi)存和運(yùn)行時(shí)間。
轉(zhuǎn)換的位置也是很重要的,看看下面的圖
方法一中,兩個(gè)數(shù)組分別產(chǎn)生8K的數(shù)據(jù),其中上面的A的8K經(jīng)過乘法后得到重用,在轉(zhuǎn)換C處,產(chǎn)生了4K的執(zhí)行數(shù)據(jù)(SGL 4BYTE),加上指示器中的操作數(shù)據(jù)4K,總計(jì)24K
方法二中,兩個(gè)數(shù)組分別產(chǎn)生8K的數(shù)據(jù),顯式轉(zhuǎn)換后,C、D處各產(chǎn)生4K的執(zhí)行數(shù)據(jù),乘法后C處的4K得到重用,加上指示器中操作數(shù)據(jù)4K,總計(jì):8k+8k+4k+4k+4k=28k
方法三中,循環(huán)中對DOUBLE數(shù)據(jù)顯式轉(zhuǎn)換成SGL,因此兩個(gè)數(shù)組各產(chǎn)生4K的數(shù)據(jù),其中A處的4K經(jīng)過乘法節(jié)點(diǎn)后得到重用,加上指示器的4K,總計(jì)12K。
對于標(biāo)量,比如DOUBLE,64位,8個(gè)字節(jié),即使發(fā)生了強(qiáng)制類型轉(zhuǎn)換,可以不必要考慮的它的內(nèi)存損失。對于字符串和數(shù)組,由于它的SIZE是很容易被改變的又沒有SIZE限制,要特別重視。
(二)數(shù)組和字符串
LABVIEW中的數(shù)組和字符串操作是最影響內(nèi)存的使用和程序的運(yùn)行速度。它影響速度的原因在于不斷調(diào)用內(nèi)存管理器來改變數(shù)組或者字符串的SIZE,LABVIEW本身也會在必要的時(shí)候改變數(shù)組和字符串的存儲位置,比如在內(nèi)存緊張的時(shí)候,可能被轉(zhuǎn)移到虛擬內(nèi)存。
上面的節(jié)點(diǎn)是需要特別注意的,因?yàn)樗鼈兌贾苯痈淖兊臄?shù)組和字符串的大小(元素個(gè)數(shù)),需要不斷地調(diào)用內(nèi)存管理器,如果是在一個(gè)循環(huán)中,會極大地降低程序的性能。
重點(diǎn)看一下BUILD ARRAY函數(shù)節(jié)點(diǎn)。
數(shù)組所占內(nèi)存的總量,等于元素個(gè)數(shù)(size)乘以每個(gè)元素所占字節(jié)數(shù)。
比如包含10000個(gè)數(shù)據(jù)的DOUBLE類型,DOUBLE 64位,8個(gè)字節(jié),占內(nèi)存總量=10K*8=80K,但這是數(shù)組最后所占的字節(jié)數(shù)。當(dāng)你改變數(shù)組大小時(shí),由于LV不能重用輸入BUFFER,必須進(jìn)行額外的內(nèi)存復(fù)制,所以在改變的過程中,會極大消耗內(nèi)存。所以為了有效地利用內(nèi)存,盡量不要在循環(huán)中改變數(shù)組或者字符串的大小。這樣就可以重用輸入BUFFER 到輸出BUFFER。
建立一個(gè)數(shù)組有很多種方式,各種方式有很大區(qū)別。
for循環(huán)是固定次數(shù)循環(huán),因此在循環(huán)開始之前,就會為索引輸出的數(shù)組申請內(nèi)存空間,一次完成,在循環(huán)內(nèi)部,不需要改變數(shù)組的大小,因此效率是最高的。
第二種方法是效率最差的,每次循環(huán)時(shí)都要增加數(shù)組的大小,循環(huán)調(diào)用內(nèi)存管理器,是需要極力避免的方法。
第三種方法用的初始化數(shù)組節(jié)點(diǎn),整個(gè)數(shù)組的的內(nèi)存空間也是一次申請的,在循環(huán)中替換數(shù)組的各個(gè)元素,而替換操作是可以重用內(nèi)存的,這也是一個(gè)常用的比較好的方法,但是FOR循環(huán)是LV的基本結(jié)構(gòu),所以無疑效率是最高的。
評論