C#中的Amdahl定律示例

win*_*sgm 14 c# multithreading

我正在努力实现一些平等化,这让我看到了阿姆达尔定律.我已经阅读了很多关于这个主题的帖子;

使用Amdahl定律计算绩效收益

如何计算线程有效性的Amadahl定律

http://en.wikipedia.org/wiki/Amdahl%27s_law

...但希望找到一个在实践中展示它的C#示例.搜索已经证明没有结果.从理论上讲,应该可以创建一个串行应用程序,对并行化部分进行计时,运行并行化版本,记录并行部分所需的长度,并将差异(知道正在使用的处理器数量)与Amdahl函数的结果进行比较.这是正确的,是否有人知道存在这样的例子?

Ale*_*ore 10

注意:可以在My Github页面上找到完整的可下载程序版本

因此,根据Amdahl定律,我们将工作分为"必须连续运行的工作"和"可以并行化的工作 ",所以让我们将这两个工作负载表示为List<Action>:

var serialWorkLoad = new List<Action> { DoHeavyWork, DoHeavyWork };
var parallelizableWorkLoad = new List<Action> { DoHeavyWork, DoHeavyWork, DoHeavyWork, DoHeavyWork, DoHeavyWork, DoHeavyWork, DoHeavyWork, DoHeavyWork };
Run Code Online (Sandbox Code Playgroud)

DoHeavyWork委托精辟抽象为:

static void DoHeavyWork()
{
    Thread.Sleep(500);
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我已经使可并行化的工作负载变得有点重,并且为它做出了一个很好的例子.

接下来,我们必须在Serial中运行两个工作负载以获得我们的基线:

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;
Run Code Online (Sandbox Code Playgroud)

此时,我们需要将每个工作负载连续运行多长时间.现在,让我们再次运行它,并行化部分并行化.

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;
Run Code Online (Sandbox Code Playgroud)

现在我们已经有了基线和并行化版本,我们可以计算加速并报告我们的发现:

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);
Run Code Online (Sandbox Code Playgroud)

正如Amdahl定律告诉你的那样,由于只有串行工作,很难用你拥有的核心来完美地扩展.