迄今為止,使用多核心的多核電腦還並沒有得到廣泛的應用。儘管在高端領域,高端伺服器的世界裡,應用著很多多核電腦系統,但在廣大的低端世界裡,還是使用著單核或雙核。但是另一方面,在膝上型電腦的世界裡,也出現了多核筆記本。
“儘管多核時代還只是對未來的預測,但不再是空想了。已經一點點地逐步靠近我們這個世界了”。
當然,還有很多單核,單一處理器的電腦被利用著,但這並不單純是C#等開發語言的應用環境。今天,主CPU的核心數量的增加趨勢越來越明顯,所以我們已經可以預見廣大使用者使用多核電腦時代的即將到來,同時以此為目標,開始我們現在的程式開發了。
首先,讓我們看一下現實情況,因為只使用到雙核,所以對核心數量的考慮還沒有那麼必要。大部分程式都只考慮把負荷很好地分散給作業系統和應用程式,至於核心,雙核就夠了。雖然有時計算量特別大的情況下程式實行平行處理是有必要的,但也只是極少數的情況。
但是,如果想首先超越這種水準的話,無論如何對於程式運行時核心數量的考慮都是有必要的。對於效能來說,增加CPU核心的做法比提高CPU時鐘頻率的做法會好很多。實際上,通過簡單的實驗,對於雙核4線程的Core
i5來說,只是運行具有多核心意識而開發出來的程式,就把速度提高了2-3倍。(當然,是針對不包含I/O等處理,而純粹運行計算處理的情況來說)。
但是,這裡有一個問題。就是如果開發程式時還要考慮核心數量的話,將會帶來很多麻煩。針對這個問題,軟體方面的對應可以說是很遲的。但是,Visual Studio
2010與.Net Framework4與C#4都率先針對這個現實問題的對應邁出了第一步。
1980年代,Occam這個開發語言有一個驚人的特點,就是它是專門針對可以實現平行處理的CPU而進行開發的。如下例所示,使用這個語言中的PAR命令,就可以實現兩個計算的平行處理。
用PAR命令來實現平行處理(Occam語言)
PAR x := x * 2 y := y * 2 |
但是,如果在C#中利用線程來實現平行處理的話,會相當麻煩。例如,只建立一個線程,並在主線程中實現並行的程式就要如下例所示。
利用線程實現平行處理(C#語言)
using System; using System.Threading; class Program { static void Main(string[] args) { var thread = new Thread(()=>Console.WriteLine("on sub thread!")); thread.Start(); Console.WriteLine("on main thread!"); thread.Join(); } } |
上例的執行結果(上下順序可以顛倒)
on main thread! on sub thread! |
必須要使用為了讓線程開始的Start方法,等待線程結束的Join方法等等,不是很智能,很簡單的。
但是,C#4的水準與Occam語言的水準很接近。不使用線程,而使用了一種全新的“任務(Task)”,如果使用封裝了這個功能的Parallel類,事情就變得簡單了。
利用任務實現平行處理(C#語言)
using System; using System.Threading.Tasks; class Program { static void Main(string[] args) { Parallel.Invoke( ()=>Console.WriteLine("1st task!"), ()=>Console.WriteLine("2nd task!")); } } |
上例的執行結果(上下順序可以顛倒)
這裡請注意用“using System.Threading.Tasks;”代替了“using
System.Threading;”。就像以前用“System.Collections.Generic;”代替“System.Collections;”那樣,改變了線程的世界。
另外,因為Parallel.Invoke方法的參數是可變的,不管多少個並行lambda運算式這裡都可以寫,可以按核心數量來寫,在多個核心之間實行平行處理。這裡由於“作為舉例來說唯寫兩個就夠了,三個以上就冗長了”的考慮,唯寫了兩個。