專題介紹 - 檢查 memory buffer 的位置與計算優化

常常在計算數據時,會使用到大量的陣列操作,
若資料量大時,則容易在計算的過程占用大量的記憶體空間,例如下圖:



32位元的使用者當完成像這樣的程式碼,你會發現程式並不能正常運作,而是顯示"memory is full"的錯誤訊息。

以 Win 7 的作業環境加上 LabVIEW 2014 的版本前提下:
32位元作業環境配上32位元軟體,可使用的記憶體空間為2GB,同時可透過設定將記憶體空間延展至3GB
64位元作業環境配上32位元軟體,可使用的記憶體空間為4GB
64位元作業環境配上64位元軟體,可使用的記憶體空間為8TB,前提是你的電腦有這麼多的記憶體。

當然換成64位元的 LabVIEW 來執行是一種方式,儘管64位元版本的程式支援的模組較少,但我們還是希望藉由這個問題來探討一下在LabVIEW中的記憶體使用量該如何來概估,以及如何來減少記憶體的使用。

首先我們要面對的,便是產生/取得的資料量到底多大這個問題。以上例而言,產生資料的元件為Initialize Array,資料型態為I32,資料長度為100000000,因此了解每一筆資料是32 bits,相當於4 bytes,再乘上資料長度後,數據空間就必須要有381.47MB,相當大的一筆資料。

但是為什麼光這樣的資料就會讓 LabVIEW崩潰?

原因是因為在進行計算的時候,程式考量資料使用分支改變等,會在某些時候重開新的記憶體空間來儲存計算前後的資料,因此依照此例,多開一個記憶體空間,那麼就會多出381.47MB。

那麼我們如何得知"某些時候"是哪些時候?此時我們需要用到的就是 Tool>>Profile>>Show buffer allocations... 這個功能。




使用者可以勾選想要查看的 Buffer allocations 種類,接下來按下 Refresh 按鈕即可。例如我們把範例簡化成這樣:




那麼當按下 Refresh 按鈕之後會變成這樣:


在 Initialize Array 的輸出點跑出一個黑點,這就代表在這邊產生了一個 memory buffer,佔了381.47MB。

如果後面多加一個 increase ,在重新檢查一次 Buffer allocations:




就會看到第一個 increase 也出現了一個 memory buffer。
由此可知,原範例中除了  Initialize Array 之外,還有20個 increase ,代表共有20個 memory buffer,這也難怪 LabVIEW 會崩潰。

那麼有什麼方法可以解決這個問題?
應用中,可能是在迴圈中產生的:



此時只需要把 tunnel 改成 shift register 即可:




此時會發現在 shift register 上主要的線路,memory buffer都消失了。他們會自動去取用 shift register上的 buffer 來用。如此就可以依情況減少  buffer 的使用!

如果不是在迴圈中,那則可以利用 In place element structure:




依此例,就只剩下 Initialize Array 的 buffer 會產生,其他的則會自動使用此 Buffer。


以上簡單介紹 Show buffer allocations 的功能以及如何減少 memory buffer 的產生。