0

を使用して次のアルゴリズムを実装しようとしましたParallel.Foreach。同期の問題がないので、並列化するのは簡単だと思いました。これは基本的にモンテカルロ木探索であり、すべての子供を並行して探索します。モンテカルロのものはそれほど重要ではありません。あなたが知っておく必要があるのは、私がいくつかの木を機能させるメソッドを持っているということParallel.Foreachです。これは、並列呼び出しが行われているスニペットです。

    public void ExpandParallel(int time, Func<TGame, TGame> gameFactory)
    {
        int start = Environment.TickCount;

        // Creating all of root's children
        while (root.AvailablePlays.Count > 0)
            Expand(root, gameInstance);

        // Create the children games
        var games = root.Children.Select(c =>
        {
            var g = gameFactory(gameInstance);
            c.Play.Apply(g.Board);
            return g;

        }).ToArray();

        // Create a task to expand each child
        Parallel.ForEach(root.Children, (tree, state, i) =>
        {
            var game = games[i];

            // Make sure we don't waste time
            while (Environment.TickCount - start < time && !tree.Completed)
                Expand(tree, game);
        });

        // Update (reset) the root data
        root.Wins = root.Children.Sum(c => c.Wins);
        root.Plays = root.Children.Sum(c => c.Plays);
        root.TotalPayoff = root.Children.Sum(c => c.TotalPayoff);
    }

デリゲートはFunc<TGame, TGame>クローンファクトリであるため、各子はゲーム状態の独自のクローンを持ちます。必要に応じてメソッドの内部を説明できますExpandが、現在のサブツリーとゲームインスタンスの状態にのみアクセスし、staticこれらのタイプのメンバーは存在しないことを保証できます。それが競合を引き起こしているのではないかと思いましたが、ループ内をEnvironment.TickCount呼び出すだけで実験を実行し、プロセッサの使用率がほぼ100%になりました。EnvironmentTickCountParallel.Foreach

Core i5では45%から50%しか使用できません。

4

1 に答える 1

2

これは、GC スラッシングの一般的な症状です。Expand メソッド内で何をしているのかを詳しく知らなくても、これが根本的な原因であると推測できます。また、リモート システムを呼び出したり、共有リソースへのアクセスをロックしたりして、一部の共有データ アクセスが原因である可能性もあります。

何かを行う前に、プロファイラーまたはその他のツールを使用して正確な原因を特定する必要があります。これはあなたの時間を無駄にするだけなので、推測しないでください。完全なプログラムがなければ答えられないので、ここで答えを待たないでください。Parallel.ForEach実験からすでにわかっているように、これを引き起こすものは何もありません。

于 2012-12-20T18:56:28.943 に答える