How To - 如何選擇正確的重入設定 (VI re-entrant execution)

想必各位在設定 VI Properties 時,都有看過下面這個設定畫面:



但是相信不少人對於左邊的 Reentrancy 設定並不知道用途是什麼,抑或是了解它的用途,但是不清楚 Shared clone reentrant execution 與 Preallocated clone reentrant execution 有何差異。

在談這個之前,要先了解重入(reentrant)是什麼樣的概念。

當subVI寫好的時候,在重入設定上預設值為 non-reentrant ,也就是不可重入的。這是指,當程式被呼叫時,non-reentrant 的程式碼會產生一個實體,被分配一個數據空間。由於它是一個實體,所以當有許多地方都需要呼叫它時,就只能等待前一個task執行完畢之後才能執行下一個task,同時使用的數據空間是同一塊。

因此有個東西叫做 Functional Global Variable (FGV),就是利用這個只有一個數據空間的特性,來達成暫存器暫存資料的功能,也利用只有一個實體的特性,來避免競賽狀態的產生。

而我們ㄧ般的程式,基本上採用 non-reentrant 的設定,也幾乎沒有問題,除一些特例之外,如下圖:





這是一個 100 次的迴圈,每個迴圈都要針對某個陣列進行計算,假設該 subVI 採用non-reentrant 的設定,雖然在迴圈中看起來是三個獨立的 VI ,但是因為 non-reentrant 故仍無法同步執行。若要讓他能同步執行,那就可以考慮設定為 Shared clone reentrant execution 或 Preallocated clone reentrant execution。

Shared clone reentrant execution 與 Preallocated clone reentrant execution 都是讓 subVI 被呼叫的時候重新產生一個實體,同時分配一塊數據空間。所以依照上圖的情況,便會變成迴圈中是三個獨立的實體進行分析,自然可以同步執行,而不需要一個等一個。也由於此時的每個 VI 都是一個實體,所以數據空間自然不互通,故 FGV 在這個狀況之下,就無法被直接呼叫使用。

那麼 Shared clone reentrant execution 與 Preallocated clone reentrant execution 又有何不同呢?

Shared clone reentrant execution 是程式執行的時候會先產生一個實體及數據空間,當該 subVI 被呼叫的時候,就把該實體及數據空間分配出去,執行完畢之後就回收。如果同時有其他地方呼叫同一個 subVI,那麼程式會額外產生一個實體,同時分配一塊數據空間,當執行結束之後同樣會回收數據空間。藉此方式來節省記憶體的使用。故如果有不特定的多處需要執行,但是執行佔時短,或是執行運算空間大的 subVI ,都可以用這個方式來節省記憶體。

Preallocated clone reentrant execution 則是單純的在程式一開始就為每一個重複呼叫的 subVI 產生一個實體與數據空間。

乍看之下 Shared clone reentrant execution 比 Preallocated clone reentrant execution 在節省記憶體方面優秀不少,但產生實體與數據空間需要花時間,同時回收也是,故執行時間效率上 Preallocated clone reentrant execution 比 Shared clone reentrant execution 來的好。因此若程式有執行佔時長,特定重複呼叫的 subVI ,都可以用這個方式來進行設定。

以上是簡易的 VI re-entrant execution 說明,希望能夠幫助到各位!