初探 .NET 中的並行運算
通常講到平行運算,情況可能是有一大筆的資料,各筆並不相關且可獨立處理,所以利用CPU或GPU的核心同時做計算。但有一種情況是,我用平行的方式或使用執行緒去處理資料,會存取到共用的變數,那實際這是並行運算。
這邊先示範一個最簡單的例子:
int total = 0;
List<int> list = new List<int>
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
};
Parallel.ForEach(list, i =>
{
Interlocked.Add(ref total, i);
Console.WriteLine(i);
});
正常情況下,如果直接對 total 這變數做運算,最後的值一定不正確,而使用Interlocked
來做加減,就可以確保 thread safe。
而解決並行運算的另一種方式,算是老方法了,即使你真的沒什麼關注新技術,這個方法你也一定會,就是使用lock
語法:
lock(lockObj)
{
TestSum++;
}
當然,有的人會覺得這方法效率較差,但影響的程式碼比較多時,用 lock 語法包起來是比較保險。當然還有另一種方式,是用前面提的Interlocked
來達成:
private static int locked = 0;
public int TestSum { get; set; } = 0;
public void TestLock()
{
bool flag = true;
while (flag)
{
if (0 == Interlocked.Exchange(ref locked, 1))
{
TestSum += 1;
//release
flag = false;
Interlocked.Exchange(ref locked, 0);
}
else
{
Console.WriteLine("locked");
}
}
}
當然這部份寫法有點麻煩,最快的方式還是用 lock 語法。
參考資料