2

.NET 4.0 で新しく強化された並列処理機能の使用に非常に興味があります。

また、C# と同様に F# で使用する可能性もいくつか見てきました。

それにもかかわらず、たとえば次のように PLINQ が提供するものしかわかりません。

var query = from c in Customers.AsParallel()
            where (c.Name.Contains("customerNameLike"))
            select c;

この並列処理の他の用途が確かにあるに違いありません。

他に使用例はありますか?これは特に PLINQ に向けられているのでしょうか、それとも PLINQ ほど簡単に使用できるものは他にありますか?

ありがとう!=)

4

3 に答える 3

4

.NET 4 で提供される新しい並列プログラミング機能は、PLINQ だけに限定されません。

Microsoft は次のように述べています。「Visual Studio 2010 と .NET Framework 4 は、新しいランタイム、新しいクラス ライブラリ タイプ、および新しい診断ツールを提供することで、並列プログラミングのサポートを強化します。これらの機能により、並列開発が簡素化されるため、効率的で細かいプログラミングを行うことができます。スレッドやスレッドプールを直接操作する必要のない、自然な慣用句による粒度の高いスケーラブルな並列コード。

良い出発点として、.NET Framework での並列プログラミングを確認することをお勧めします。

全体として、.NET 4 と Visual Studio 2010 は次の機能を提供します。

個人的には、Task Parallel Library の Task クラスと Task{T} クラスの方が、非同期作業を作成および調整する際により柔軟であることがわかりました。

于 2010-05-28T00:25:32.883 に答える
2

私のチームもこれに関する本を完成させました...

Microsoft® .NE​​T による並列プログラミング: マルチコア アーキテクチャでの分解と調整のための設計パターン

コリン・キャンベル、ラルフ・ジョンソン、エイド・ミラー、スティーブン・トゥーブ。トニー・ヘイによる序文

ドラフトとサンプルは、http: //parallelpatterns.codeplex.com/からダウンロードできます。

完全な書籍は、今月末に MSDN で、10 月に Amazon で入手できるようになります。

露骨なプラグインで申し訳ありませんが、内容は本当に役立つと思います.

アップデート...

あなたが選んだ問題 (以下) の質問に答えるために、Aggregation の実装 (リストから、リストの内容に基づいて集計を作成する) は、別の Parallel.ForEach よりもはるかにうまく PLinq にマップされます。PDF の p72 に Parallel.ForEach を使用した集計の例があります。

PLinq を使用してセットの内容を更新するだけの場合、マッピングははるかに簡単です。たとえば、次のコードは口座のリストをループし、残高の傾向を計算し、当座貸越限度を超える予測残高を持つ口座にフラグを立てます。

一連の:

static void UpdatePredictionsSequential(AccountRepository accounts)
{
    foreach (Account account in accounts.AllAccounts)
    {
        Trend trend = SampleUtilities.Fit(account.Balance);
        double prediction = trend.Predict(account.Balance.Length + NumberOfMonths); 
        account.SeqPrediction = prediction;
        account.SeqWarning = prediction < account.Overdraft;
    }
}

プリンク:

static void UpdatePredictionsPlinq(AccountRepository accounts)
{            
    accounts.AllAccounts
        .AsParallel()
        .ForAll(account =>
            {
                Trend trend = SampleUtilities.Fit(account.Balance);
                double prediction = trend.Predict(account.Balance.Length + NumberOfMonths);
                account.PlinqPrediction = prediction;
                account.PlinqWarning = prediction < account.Overdraft;         
            });
}

Parallel.ForEach:

static void UpdatePredictionsParallel(AccountRepository accounts)
{
    Parallel.ForEach(accounts.AllAccounts, account =>
    {
        Trend trend = SampleUtilities.Fit(account.Balance);
        double prediction = trend.Predict(account.Balance.Length + NumberOfMonths);
        account.ParPrediction = prediction;
        account.ParWarning = prediction < account.Overdraft;
    });
}

場合によっては、PLinq が最も表現力のある選択肢になることがあります。Parallel.For/ForEach の方が優れている場合もありますが、場合によっては、主にプログラマの好みの問題です。

ただし、Task Parallel Library は、Parallel Loop および Aggregation パターン以外にもサポートしています。マルチコア ハードウェアでの並列実行用にスケジュールされるタスクを構築できます (タスク並列処理パターン)。

static int ParallelTaskImageProcessing(Bitmap source1, Bitmap source2,
                                    Bitmap layer1, Bitmap layer2, Graphics blender)
{
    Task toGray = Task.Factory.StartNew(() => SetToGray(source1, layer1));
    Task rotate = Task.Factory.StartNew(() => Rotate(source2, layer2));
    Task.WaitAll(toGray, rotate);
    Blend(layer1, layer2, blender);
    return source1.Width;
} 

あるタスクの出力が別のタスクに供給されるタスクのグラフを作成できます (タスク グラフまたはフューチャー パターン)。

public static int Example4()
{
    var a = 22;

    var cf = Task<int>.Factory.StartNew(() => F2(a));
    var df = cf.ContinueWith((t) => F3(t.Result));
    var b = F1(a);
    var f = F4(b, df.Result);
    return f;
}

F1-F4 は、入力と出力に依存関係がある関数です。

ソートなどの分割統治の問題 (動的タスク並列処理パターン) のために、依存タスクのツリーの作成をサポートします。

static void ParallelWalk<T>(Tree<T> tree, Action<T> action)
{
    if (tree == null) return;
    var t1 = Task.Factory.StartNew(
               () => action(tree.Data));
    var t2 = Task.Factory.StartNew(
               () => ParallelWalk(tree.Left, action));
    var t3 = Task.Factory.StartNew(
               () => ParallelWalk(tree.Right, action));
    Task.WaitAll(t1, t2, t3);
}

また、並列プログラムで使用するための (スレッドセーフな) コレクションもいくつか実装しています。これにより、たとえば Pipeline パターンを簡単に実装できます。

static void Chapter7Example01Pipeline(int seed)
{
    Console.Write("Begin Pipelined Sentence Builder");

    var buffer1 = new BlockingCollection<string>(BufferSize);
    var buffer2 = new BlockingCollection<string>(BufferSize);
    var buffer3 = new BlockingCollection<string>(BufferSize);

    var f = new TaskFactory(TaskCreationOptions.LongRunning, 
                            TaskContinuationOptions.None);

    var stage1 = f.StartNew(() => ReadStrings(buffer1, seed));
    var stage2 = f.StartNew(() => CorrectCase(buffer1, buffer2));
    var stage3 = f.StartNew(() => CreateSentences(buffer2, buffer3));
    var stage4 = f.StartNew(() => WriteSentences(buffer3));

    Task.WaitAll(stage1, stage2, stage3, stage4);
}

上記のすべての機能には、例外処理とキャンセルのサポートも含まれていますが、わかりやすくするためにここでは示していません。

于 2010-08-06T05:53:42.327 に答える
1

39:30から 48:36 までのScott Hanselman のプレゼンテーションをご覧ください。(トーク開始39分30秒あたりから)

于 2010-05-28T00:27:06.427 に答える