注:該程序的一個完整的工作可下載的版本可以在My Github Page
因此,與Amdahl定律被發現,大家平分到工作和「工作「的工作,必須連續運行」可以並行」,讓我們代表這兩個工作負載List<Action>
:
var serialWorkLoad = new List<Action> { DoHeavyWork, DoHeavyWork };
var parallelizableWorkLoad = new List<Action> { DoHeavyWork, DoHeavyWork, DoHeavyWork, DoHeavyWork, DoHeavyWork, DoHeavyWork, DoHeavyWork, DoHeavyWork };
凡DoHeavyWork
委託精闢抽象爲:
static void DoHeavyWork()
{
Thread.Sleep(500);
}
正如你所看到的,我已經使可並行化的工作負載變得更加有趣,並且讓它成爲一個體面的例子。
接下來我們要在串口同時運行工作負載,讓我們的基線:
var stopwatch = new Stopwatch();
stopwatch.Start();
// Run Serial-only batch of work
foreach (var serialWork in serialWorkLoad)
{
serialWork();
}
var s1 = stopwatch.ElapsedMilliseconds;
// Run parallelizable batch of work in serial to get our baseline
foreach (var notParallelWork in parallelizableWorkLoad)
{
notParallelWork();
}
stopwatch.Stop();
var s2 = stopwatch.ElapsedMilliseconds - s1;
在這一點上,我們有多久了每個工作負荷在連續運行。現在,讓我們再次運行它,並行化部分。
stopwatch.Reset();
stopwatch.Start();
// Run Serial-only batch of work
foreach (var serialWork in serialWorkLoad)
{
serialWork();
}
var p1 = stopwatch.ElapsedMilliseconds;
// Run parallelizable batch of work in with as many degrees of parallelism as we can
Parallel.ForEach(parallelizableWorkLoad, (workToDo) => workToDo()); // In Java this is Magic Unicorns
stopwatch.Stop();
var p2 = stopwatch.ElapsedMilliseconds - p1;
現在,我們有基線和並行版本,我們可以計算出加速和報告我們的發現:
var speedup = (double)(s1 + s2)/(p1 + p2);
Console.WriteLine("Serial took : {2}ms, {0}ms for serial work and {1}ms for parallelizable work", s1, s2, s1 + s2);
Console.WriteLine("Parallel took: {2}ms, {0}ms for serial work and {1}ms for parallelizable work", p1, p2, p1 + p2);
Console.WriteLine("Speedup was {0:F}x", speedup);
而作爲Amdahl定律告訴你,這是很難與完美比例由於僅使用串行工作而導致的內核數量。
這是一個很好的問題。 Upvoted和收藏。 – Brian
齶化? –