More Related Content
Similar to Net Parallel Programming .NET平行處理與執行序
Similar to Net Parallel Programming .NET平行處理與執行序 (20)
More from HO-HSUN LIN (7)
Net Parallel Programming .NET平行處理與執行序
- 8. THREADS
簡單的Thread範例
ThreadStart 是委派(delegate)函式,經由Thread類別建立實體,呼叫Start函式執行
Alpha alpha = new Alpha();
Thread thread = new Thread(new ThreadStart(alpha.Beta));
thread.Start();
8
- 12. MULTITHREADING VS PARALLEL
多執行序
長時間處理時,維持UI程式的反應
允許多個需求和過程可以分別被處理
卸載可以發生在應用程式的背後
平行程式
計算效能提高
效能與核心/處理器數量呈正比,並在核心/處理器數量增加時,不需要程式碼來指定硬體的設定
12
- 20. CONCURRENT COLLECTIONS
Thread-safe collection
ConcurrentStack
ConcurrentQueueo
ConcurrentDictinary
Work exchange
BlockingCollection
IProducerConsuerCollection
Initialization
LazyInit
Phased Operation
CountdownEvent
Barrier
Lock
ManualResetEventSlim
SemaphoreSlim
SpinLock
SpinWait
20
- 21. 平行執行
1. Tasks
2. The Task Parallel Library (TPL):
1. For
2. Foreach
3. Invoke
3. Parallel LINQ (PLINQ)
21
- 28. DEMO 1 : TASKS
Task programming model
給予更多控制的thread
Return Result
Task Channing
28
- 29. DEMO 1 : TASKS
Task 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");
});
29
- 30. DEMO 1 : TASKS
Task t2 = null;
t2 = Task.Factory.StartNew(() =>
{
Thread.Sleep(1000);
return "Result of Task 2";
});
string result = t2.Result;
Console.WriteLine(result);
30
- 31. DEMO 2 : PARALLEL
這裡使用了For method,對照Serially method
Parallel Loop
Parallel.For
31
- 32. DEMO 2 : PARALLEL
Stopwatch watch = new Stopwatch();
watch.Start();
for (int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
}
watch.Stop();
Console
.WriteLine(watch.Elapsed.Seconds.ToString());
32
- 33. DEMO 2 : PARALLEL
Stopwatch watch = new Stopwatch();
watch.Start();
System.Threading.Tasks.Parallel
.For(0, 10, i =>
{
Thread.Sleep(1000);
});
watch.Stop();
Console
.WriteLine(watch.Elapsed.Seconds.ToString());
33
- 34. DEMO 3 : PLINQ
Parallel LINQ 是 LINQ to Objects 的實作(implement)
For和LINQ執行時間幾乎相同,使用PLINQ執行時間快了一倍
Parallel.Invoke
34
- 35. DEMO 3 : PLINQ
int[] 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);
35
- 36. DEMO 3 : PLINQ
int[] 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);
36
- 37. DEMO 3 : PLINQ
int[] 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);
37
- 38. DEMO 4 : RACE CONDITION
數據競爭
遞增特定變數並將結果儲存起來,成為不可分割完成的作業
38
- 39. DEMO 4 : RACE CONDITION
int 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());
39
- 40. DEMO 4 : RACE CONDITION
int 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());
40
- 41. DEMO 4 : RACE CONDITION
int 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());
41
- 42. DEMO 5 : DEADLOCKS
使用鎖定(lock)可能會造成死結(Deadlocks)
Nested/Child Tasks
42
- 43. DEMO 5 : DEADLOCKS
static 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;
}
}
43
- 44. DEMO 5 : DEADLOCKS
static void Transfer(Account one, Account two, int amount)
{
lock (one)
{
lock (two)
{
one.amount -= amount;
two.amount += amount;
}
}
}
class Account
{
public int amount;
}
44
- 45. DEMO 5 : DEADLOCKS
class 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));
}
}
45
- 47. CONCLUSION
Parallel .NET 降低了 multi-thread 的複雜度
更好的控制方法
Parallel Loop
For
Foreach
Invoke
執行序安全物件
ConcurrentDictionary
ConcurrentQueue
ConcurrentStack
還是要注意 multi-thread 的問題
Race Condition
Deadlock
47
Editor's Notes
- Thread-safe collection
ConcurrentStack 後進先出(Last In-First Out)
ConcurrentQueue 先進先出(FIFO)
ConcurrentDictinary
Work exchange
BlockingCollection
IProducerConsuerCollection
Initialization
LazyInit
Phased Operation
CountdownEvent
Barrier
Lock
ManualResetEventSlim 告知一個以上的等候中執行緒已發生事件
SemaphoreSlim 限制可以同時存取資源或資源集區的執行緒數目
SpinLock
SpinWait
- 查詢分析
WithExecutionMode - 強制平行運算
分割
chunk
來源資料沒法被加上索引時使用
range
確認執行序的數量,將輸入來源分割成最佳化的大小,會在資料室可使用索引時被選擇
高效能,沒有同步需求
striped
給資料前端做處理和評估的標準查詢運算子用
hash
給需要比較資料元素查詢用的,分割相同鍵雜湊碼數值的元素給同一個執行序
節省分割負載時間
- 分割
chunk
來源資料沒法被加上索引時使用
range
確認執行序的數量,將輸入來源分割成最佳化的大小,會在資料室可使用索引時被選擇
高效能,沒有同步需求
striped
給資料前端做處理和評估的標準查詢運算子用
hash
給需要比較資料元素查詢用的,分割相同鍵雜湊碼數值的元素給同一個執行序
節省分割負載時間