14

私はいくつかの並列化に取り組んでいたので、アムダールの法則を調べました。このトピックに関するいくつかの投稿を読みました。

アムダールの法則を使用してパフォーマンスの向上を計算する

糸脱毛の有効性に関するアマダールの法則を計算する方法

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

...しかし、実際にそれを示すC#の例を見つけることを望んでいました。検索しても結果は得られませんでした。理論的には、シリアルアプリケーションを作成し、並列化可能な部分の時間を計測し、並列化されたバージョンを実行し、並列部分にかかる長さを記録し、その差(使用されているプロセッサの数を知る)をアムダールの関数の結果と比較することが可能です。これは正しいですか、そして誰かがそのような例が存在することを知っていますか?

4

1 に答える 1

10

注:プログラムの完全に機能するダウンロード可能なバージョンは、MyGithubページにあります。

したがって、アムダールの法則を使用して、作業を「シリアルで実行する必要がある作業」と「並列化できる作業」に分割します。したがって、これら2つのワークロードを次のように表し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);

アムダールの法則が示すように、シリアルのみの作業のため、コアの数に完全に対応することは困難です。

于 2013-01-16T06:39:02.797 に答える