摘要:本文主要介紹了專門針對多核應用而優化的全新LabVIEW軟件,并詳細介紹其開發優勢。
關鍵詞:LabVIEW;多核;并行處理;并行編程
多核時代的編程挑戰
眾所周知,由于對芯片功率和熱效應的制約,以往單純通過提高主頻來提高處理器運行速度的做法已經不再可行,一個新的架構已經逐漸成型,那就是多核。

多核時代的來臨已成為主流的發展趨勢,在2006年的Intel開發者論壇上,Intel的CEO Paul Otellini向全世界展示了一個80核的原型,它可以在一秒內處理數以千兆字節的數據,那是非常驚人的處理能力,并且Intel希望在5年內將其推入消費市場。
然而,這對于工程師和程序員們來說,意味著什么呢?
在以往,程序開發人員們只需換上一塊更高計算性能的處理器,就可以在無需任何代碼修改的情況下,自動加快了每一行代碼的執行速度。然而在如今的多核時代,這樣的“免費午餐”已經結束了。如圖1所示,即使是在一個4核處理器上,如果其應用只是單線程的話,操作系統仍舊會將所有的任務分配到其中一個核上運行,導致多核處理器無法得到充分的利用。因此,為了充分利用多核處理器,需要有新的編程方法。
而這恰恰是一個巨大的編程挑戰,針對這個問題,比爾蓋茨也說過:“要想充分利用并行工作的處理器威力,……軟件必須能夠處理并發性問題。但正如任何一位編寫過多線程代碼的開發者告訴你的那樣,這是編程領域最艱巨的任務之一。”
總體而言,多核處理器編程存在以下幾大難點:首先是并行的思考方式,比如要分辨出哪些任務是可以同時執行的,這并不是一件容易的事情,尤其對于習慣于順序結構編程的開發人員來說,思考方式的轉變往往需要花相當長的一段時間。
其次是線程的創建和管理。開發人員把任務劃分成多個并行步驟之后,就要通過線程的方式來編程實現。事實上,多線程編程是相當困難的,很多傳統的編程語言都需要一組新的函數或結構來創建、同步、加解鎖線程,這意味著工作量的增加。例如用C++寫一個多線程的程序,程序員就必須要非常熟悉C++,了解如何將C++程序分成多個線程和任務間并發的同步,此外還要了解Windows多線程的機制,熟悉WindowsAPI的調用方法,或者MFC的架構等等;在C++上調試多線程程序,更是被許多程序員視為噩夢。

最后,開發人員還需要自己考慮并行代碼段之間哪些資源是不能共享的,比如文件、內存、硬件等等,否則會導致資源的沖突和爭奪,使得并行線程因等待資源而暫停甚至死鎖。
以往基于文本的編程語言,由于其自身是一種順序的編程模式,因此在對待并行編程時顯得有些力不從心。雖然對于一些學習計算機編程或軟件工程的專業開發人員來講,使用文本語言在一個雙核處理器中開發并行編程機制可能還不足以被難倒的話,那么當Intel推出80核處理器之后,其編程的復雜度相信任何開發人員都無法應付。因此,工程師和開發人員們都期待著一種更高效、更具創新的并行編程工具,能夠協助他們順利迎接多核時代的到來。
LabVIEW-天生并行的編程語言
LabVIEW就是這樣一種馳騁多核技術時代的編程語言,可以幫助開發人員高效地享用多核技術所帶來的益處。
LabVIEW是一個基于數據流的圖形化開發平臺,它提供了直觀的圖形化編程方式和用戶界面。與傳統的文本編程相比,LabVIEW天生就是一種并行結構的編程語言。基于LabVIEW的數據流特性,如果連線中存在著分支,或者是框圖中有著并行序列,那么后臺的LabVIEW執行器就將自動地實現并行化運行,這種在計算機科學術語中叫做“潛在并行化”(圖2)。例如,我們在LabVIEW下創建了多個循環,那么相對應的也就創建了數個新的執行線程,從而這些并行循環就會自動分配成多個線程分到多個處理核上,讓LabVIEW開發人員享受到了多核處理器的性能優勢。
從單核到雙核的處理器,理論上來說,獲得的運算性能可以達到原先的兩倍。但是,與這個極限值的接近程度取決于用戶應用程序并行化運行的程度。使用LabVIEW,我們就可以方便地實現應用程序性能的改進,通過最少的編程調整,并行應用便可以獲益于多核處理器。對于普通的LabVIEW應用程序而言,如果不考慮多核編程技巧,在不改寫代碼的情況下,與最初的基準程序相比,可以獲得25%到35%性能上的提升,這也就意味著“免費的午餐”還沒有結束。
下面我們來看圖3的簡單例子。其中LabVIEW代碼中的分支簡化了兩個分析任務——濾波操作和快速傅立葉變換(FFT),使它們可以在雙核機器上并行化執行。首先程序在單核的模式下(關閉其中一個核)運行一次,然后在雙核模式下運行。從圖中可以看到,由于兩項任務的計算量都很高,因此利用任務并行化獲得的性能改進為原先的1.8倍。
Windows操作系統是自動將線程分配到不同的核上,那么對于某些應用,如果有一個對時間要求非常高的線程,那么是否有辦法能夠保證它執行的確定性呢?
使用LabVIEW就可以很好地解決這個問題,從而獲得對于多核處理器更多的控制權。在LabVIEW中,工程師可以根據自身需求手動設置線程運行在特定的核上,例如將時間要求苛刻的采集與控制任務放在單獨的核上運行,而將對確定性要求不高的界面響應、數據記錄等任務放在另外一個核上運行(圖4)。值得一提的是,實現這樣的操作非常簡單,就像放一個LabVIEW循環一樣,只需放置一個定時循環(Timed Loop),再分配那個循環到指定的核上即可。
作為一個典型的多核應用案例,德國的Max Planck研究院要實現針對核聚變能源的受控熱核反應裝置的等離子控制,這種高速控制需要將88個磁感應器上的大量數據轉換為64×128個點格上的偏微分方程組,并要在短短的1ms內完成整個計算過程。最終他們使用LabVIEW在一個8核的系統上采用并行技術,將整個系統的運算速度提高了5倍,成功地達到了1ms閉環控制速率的要求,完成了這個“不可能的任務”。基于LabVl EW的并行編程
LabVIEW自身所具有的并行特性使得開發人員可以不用花過多的時間放在多線程的創建、管理、同步、調試等底層實現過程上,而可以將主要精力聚焦在整個并行程序的高層架構上,這是能否高效利用多核處理器技術的關鍵所在。
本節中將簡單介紹針對多核的三種常用編程方式及其在LabVIEW下的實現方式。
任務并行化(TaskParallelism)
將整個程序分成多個線程來并發運行,是并行編程的一個基本理念,那么通常一個程序都會由幾個子任務組成,例如在某個測試測量程序中,就可以分為模擬采集和數字輸出兩個任務,那么如果我們將這些獨立的任務并發地執行在多核處理器中,那么就自動提高了運行的效率。這種將獨立的幾個任務在程序中并發執行的方法,就叫做任務并行化。

對于任務并行化,如何合理地去實現任務分配是需要解決的問題。首先,我們可以將本身就互相獨立的任務分配在不同線程中,如上例所提到的模擬采集與數字輸出任務,之間就沒有任何的數據連接,因此在LabVIEW中我們就可以并行地將代碼放在程序框圖中,不需要添加任何其他代碼,如圖5所示。
此外,編程中常見的生產者一消費者循環也是一種任務并行化,在LabVIEW下我們可以將生產者(讀取數據)與消費者(分析數據)分成并行的兩個任務,任務之間的數據交互可以使用隊列結構(Queue)來實現,如圖6所示。
數據并行化(Data ParalIeIism)
除了可以將程序任務進行并行化之外,對于一些海量數據的處理分析,我們還可以將數據分成幾個可并行操作的小數據集,然后分別在各個核上實現并行處理,最后將結果整合起來作為整體數據集的處理分析結果,這種方式稱為數據并行化。
如圖7(a)所示,一個大的數據集僅僅在一個核上進行處理和運算,當核1在處理數據時,其它的三個CPU核都處在閑置狀態,整個系統的運行效率很低。
那么,使用了數據并行化之后,如圖7(b),之前的大數據集被分割成4個小數據集,并將它們在各自的核上進行處理運算,最終再將各自的運算結果整合起來作為大數據集的處理結果。經過了數據并行化之后,整個系統的運算效率有了直線的提升。
與“任務并行化”類似,在LabVIEW下實現“數據并行化”也相當的直觀與方便,圖8就顯示了一個矩陣相乘的代碼,程序中將兩個大矩陣各自分割成小矩陣進行相乘,最后再整合起來,僅僅這樣一個簡單的改變就可以在一個雙核處理器上得到0.9倍的性能提高。

流水線式(Pipeline)
流水線,顧名思義,就是指將一系列的任務分割成固定的幾個步驟,然后按照裝配線的方式來執行。
我們以一個最簡單的汽車裝配線為例,一輛車的裝配完成需要3個步驟:底盤安裝、零件安裝以及上漆。如果每個步驟都需要花費1個小時的話,那么如果一次就裝配一輛車的話,我們需要花3個小時來完成(圖9a)。
那么,如果我們換一種思路,分別對每個步驟設立一個工作站(例如工作站1就專門負責底盤安裝,以此類推,如圖9b)。這樣一來,我們看到,當一輛車在上漆時,另外一輛車可能正在進行底盤安裝。通過這種方式,我們成功實現了每一個小時就能完成一輛車的裝配,是之前裝配速度的3倍。這個例子中所說的工作站,其實就可以算作是CPU各個核,那么通過這種流水線的操作方式,就可以充分利用多核技術,大大提高整個程序的運行速率。
而在LabVIEW下實現流水線式編程也是非常方便,圖10就是一個最簡單的4個步驟的流水線式代碼,在一個For循環中,并行地執行4個處理步驟,系統將這并行的4個步驟放在不同的核上運行,從而起到“工作站”的作用,實現了流水線式的編程。

綜上所述,任務并行化、數據并行化以及流水線式是并行編程的三種最常用的方式,相對于以往的順序結構,這些編程方式可以在多核處理器上發揮更強大的作用,而在LabVIEW下可以很方便地實現這些編程方式,從而幫助工程師們從多核處理器技術中得益,提升系統的性能和運算速度。
結語
隨著新一代處理器技術的日益普遍,工程師與開發人員的一個必要考慮因素就是他們使用的軟件如何從多核系統中獲得潛在的性能提升。LabVIEW作為天生并行的圖形化編程環境,可以自動將程序多線程化,避免了開發人員繁瑣的底層實現,將主要精力投入在高層的編程模式上;而作為并行編程的三種常用模式(任務并行化、數據并行化以及流水線式),在LabVIEW下也都能高效地予以實現。因此,不容置疑的是,隨著具有更多核的處理器不斷涌現,LabVIEW將幫助開發人員真正邁入并行,馳騁多核技術時代!