を使用して次のアルゴリズムを実装しようとしました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%になりました。EnvironmentTickCount
Parallel.Foreach
Core i5では45%から50%しか使用できません。