Parallel.Foreach
을 사용하여 다음 알고리즘을 구현하려고했습니다. 내가 동기화 문제가 없기 때문에 평행하게 만드는 것이 사소한 것이라고 생각했다. 기본적으로 Monte-Carlo tree 검색으로, 모든 어린이를 평행하게 탐구합니다. 몬테 - 카를로 (Monte-Carlo)의 내용은별로 중요하지 않습니다. 여러분이 알아야 할 것은 나무를 사용하는 방법과 루트 자식에 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
이 경쟁을하고 있을지도 모른다고 생각했지만, EnvironmentTickCount
을 Parallel.Foreach
루프 안에 넣고 거의 100 % 프로세서 사용법을 사용하는 실험을 실행했습니다.
코어 i5에서만 45 % ~ 50 % 사용.
여기에서 프로파일 링을 위해 권장되는 접근 방법은 무엇입니까? 이전에는 컨 텐션 프로파일 링을 한 번도 해본 적이 없으며 VS2012 프로파일 러는 너무 많은 데이터를 보여줌으로써 병목 현상을 빨리 피할 수 없습니다. 성능 프로파일 러에서 가장 비싼 함수와 호출을 빠르게 볼 수 있지만 컨텐트 프로파일러의 경우에는 아무 것도 찾을 수 없습니다. 미리 감사드립니다. –