net parallel programming
TRANSCRIPT
1
.Net Parallel framework
2
Agenda
Introduction
Concurrency
Parallel Extensions
Parallel Programming
Conclusion
3
Introduction從單核心轉變到多核心的平行處理,在重疊的時間執行多個運算
Introduction
Concurrency
Parallel Extensions
Parallel Programming
Conclusion
4
Introduction
5
Introduction從單核心轉變到多核心的平行處理,在重疊的時間執行多個運算• 回應式介面 (Responsive UI)• 非同步程序 (Asynchronous)• 更好的效能 (Performance)
6
Concurrency Introduction
Concurrency
Parallel Extensions
Parallel Programming
Conclusion
7
Threads
8
Threads• 簡單的 Thread 範例• ThreadStart 是委派 (delegate) 函式,經由
Thread 類別建立實體,呼叫 Start 函式執行Alpha alpha = new Alpha();
Thread thread = new Thread(new ThreadStart(alpha.Beta));
thread.Start();
9
Concurrency Challenges• 同步問題• Race Condition• Deadlock
• 倚賴記憶體和硬體架構支援• 除錯困難
10
Amdahl's law
平行運算之後效率提升 整體效能獲得• 1 = ((1-P) +
(P/Speedup))• P : 支援平行運算的部分• Speedup = CPU 的數量
圖片來源: Wiki
11
Multithreading vs Parallel
• Multithreading :Overlapping time periods 在重疊的時間執行多個運算• Parallel :
Simultaneously 同時執行多個運算
圖片來源: MSDN
12
Multithreading vs Parallel• 多執行序• 長時間處理時,維持 UI 程式的反應• 允許多個需求和過程可以分別被處理• 卸載可以發生在應用程式的背後
• 平行程式• 計算效能提高• 效能與核心 / 處理器數量呈正比,並在核心 / 處理器數量增加時,不需要程式碼來指定硬體的設定
13
Multithreading• 用多執行序來做平行程式的問題• 複雜的撰寫• race condition
• 執行序的數量最好跟 CPU 一樣• 並不是每一項工作都在相同時間完成
14
Multithreading• 是同時處理多個獨立的任務 (task) ,在邏輯
(logically) 上是獨立的,主要目的是避免延遲(latency)• 當多個執行緒 (thread) 同時執行,如果需要共享系統資源,要面對死結 (deadlocks) 和數據競爭 (race condition) 的問題,使得除錯變得極其困難和複雜
15
Parallel• 實際 (realistic) 將任務 (task) 分割成一組相關的任務,同時執行• 同樣也有死結 (deadlocks) 和數據競爭 (race
condition) 的問題,還有資源共享 (sharing)和資料分區 (partitioning) ,這讓除錯變得極其困難和複雜
16
Limitations• Serial Code• Sequential input/output•同步 (Synchronization)
17
Parallel Extensions Introduction
Concurrency
Parallel Extensions
Parallel Programming
Conclusion
18
Task Parallelism• 分解程序分成部分例如方法,報表等• 識別哪些可以並行執行的部分• 分配每部分單獨任務• 在不同核心 (Core) 並行執行的任務• 每個任務有可能執行不同的操作
19
Architecture
圖片來源: MSDN
20
Concurrent Collections• Thread-safe collection
• ConcurrentStack• ConcurrentQueueo• ConcurrentDictinary
• Work exchange• BlockingCollection• IProducerConsuerColle
ction• Initialization
• LazyInit
• Phased Operation• CountdownEvent• Barrier
• Lock• ManualResetEventSlim• SemaphoreSlim• SpinLock• SpinWait
21
平行執行1. Tasks2. The Task Parallel Library (TPL):
1. For2. Foreach3. Invoke
3. Parallel LINQ (PLINQ)
22
合併平行結果• 控制的時機• 處理分割後• 緩衝結果直到所有的分割都完成
• AsParallel• AsOrdered• Sorting
23
查詢分析• WithExecutionMode - 強制平行運算
24
分割• Chunk• 來源資料沒法被加上索引時使用
• Range• 確認執行序的數量,將輸入來源分割成最佳化的大小
• Striped• 給資料前端做處理和評估的標準查詢運算子用
• Hash• 給需要比較資料元素查詢用的
25
Work Stealing
圖片來源: A Java Fork/Join Doug Lea
26
Overhead• 工作分割有一個最佳的大小,需要測試才能確定• 執行時間需比分割負載的時間長• 同步、平行分割的部分相互輔助• 平行工作越獨立越好,任何一個外來的同步,都會降低效能和發生不容易除錯的 race
condition
27
Parallel Programming Introduction
Concurrency
Parallel Extensions
Parallel Programming
Conclusion
28
Demo 1 : Tasks• Task programming model• 給予更多控制的 thread• Return Result• Task Channing
29
Demo 1 : TasksTask t1 = null;
t1 = Task.Factory.StartNew(() =>{
Console.WriteLine("Task 1");});Console.WriteLine("Main");
var t2 = t1.ContinueWith(delegate{
Thread.Sleep(1000);Console.WriteLine("Continue With Task 1");
});
30
Demo 1 : TasksTask t2 = null;
t2 = Task.Factory.StartNew(() =>{
Thread.Sleep(1000);return "Result of Task 2";
});
string result = t2.Result;Console.WriteLine(result);
31
Demo 2 : Parallel• 這裡使用了 For method ,對照 Serially
method• Parallel Loop• Parallel.For
32
Demo 2 : ParallelStopwatch watch = new Stopwatch();
watch.Start();for (int i = 0; i < 10; i++){
Thread.Sleep(1000);}watch.Stop();
Console.WriteLine(watch.Elapsed.Seconds.ToString());
33
Demo 2 : ParallelStopwatch watch = new Stopwatch();
watch.Start();System.Threading.Tasks.Parallel
.For(0, 10, i =>{Thread.Sleep(1000);});
watch.Stop();
Console.WriteLine(watch.Elapsed.Seconds.ToString());
34
Demo 3 : PLINQ• Parallel LINQ 是 LINQ to Objects 的實作
(implement)• For 和 LINQ 執行時間幾乎相同,使用 PLINQ執行時間快了一倍• Parallel.Invoke
35
Demo 3 : PLINQint[] array = Enumerable.Range(0, 20000).ToArray();bool[] results = new bool[array.Length];
Stopwatch watch = new Stopwatch();
watch.Start();for (int i = 0; i < array.Length; i++){
//質數results[i] = IsPrime(array[i]);
}watch.Stop();
Console.WriteLine(watch.Elapsed.Seconds);
36
Demo 3 : PLINQint[] array = Enumerable.Range(0, 20000).ToArray();bool[] results = new bool[array.Length];
Stopwatch watch = new Stopwatch();
watch.Start();//質數results =
array.Select(x => IsPrime(x)).ToArray();
watch.Stop();
Console.WriteLine(watch.Elapsed.Seconds);
37
Demo 3 : PLINQint[] array = Enumerable.Range(0, 20000).ToArray();bool[] results = new bool[array.Length];
Stopwatch watch = new Stopwatch();
watch.Start();//質數results =
array.AsParallel().Select(x => IsPrime(x)).ToArray();
watch.Stop();
Console.WriteLine(watch.Elapsed.Seconds);
38
Demo 4 : Race Condition• 數據競爭• 遞增特定變數並將結果儲存起來,成為不可分割完成的作業
39
Demo 4 : Race Conditionint counter = 0;Object o = new Object();Stopwatch watch = new Stopwatch();
watch.Start();Parallel.For(0, 100000, i =>{
Thread.Sleep(1);counter++;
});watch.Stop();
Console.WriteLine(watch.Elapsed.Seconds);Console.WriteLine(counter.ToString());
40
Demo 4 : Race Conditionint counter = 0;Object o = new Object();Stopwatch watch = new Stopwatch();
watch.Start();Parallel.For(0, 100000, i =>{
Thread.Sleep(1);lock (o){counter++;}
});watch.Stop();
Console.WriteLine(watch.Elapsed.Seconds);Console.WriteLine(counter.ToString());
41
Demo 4 : Race Conditionint counter = 0;Object o = new Object();Stopwatch watch = new Stopwatch();
watch.Start();Parallel.For(0, 100000, i =>{
Thread.Sleep(1);Interlocked.Increment(ref counter);
});watch.Stop();
Console.WriteLine(watch.Elapsed.Seconds);Console.WriteLine(counter.ToString());
42
Demo 5 : Deadlocks• 使用鎖定 (lock) 可能會造成死結 (Deadlocks)• Nested/Child Tasks
43
Demo 5 : Deadlocksstatic void Main(string[] args){
int transfers = 0;Deadlock.Break(() => transfers, 500);
Account a = new Account { amount = 1000 };Account b = new Account { amount = 1000 };
while (true){Parallel.Invoke(() => Transfer(a, b, 100),() => Transfer(b, a, 100));transfers += 2;}
}
44
Demo 5 : Deadlocksstatic void Transfer(Account one, Account two, int amount){
lock (one){lock (two){one.amount -= amount;two.amount += amount;}}
}
class Account{
public int amount;}
45
Demo 5 : Deadlocksclass Deadlock{
private static ConcurrentQueue<Timer> queue = new ConcurrentQueue<Timer>();public static void Break<T>(Func<T> value, int milliseconds) where T :
IEquatable<T>{bool initialized = false;T last = default(T);queue.Enqueue(new Timer(t =>{T current = value();if (initialized && last.Equals(current)){Debugger.Break();}initialized = true;last = current;}, null, milliseconds, milliseconds));}
}
46
Conclusion Introduction
Concurrency
Parallel Extensions
Parallel Programming
Conclusion
47
Conclusion• Parallel .NET 降低了 multi-thread 的複雜度
• 更好的控制方法• Parallel Loop
• For• Foreach• Invoke
• 執行序安全物件• ConcurrentDictionary• ConcurrentQueue• ConcurrentStack
• 還是要注意 multi-thread 的問題• Race Condition• Deadlock
48
THANKS