在Rust的Rayon并行循环中求成功总和。

huangapple go评论70阅读模式
英文:

Summing successes inside of a Rayon Parallelized for loop in Rust

问题

在编译时出现了"Cannot assign to won_games, as it is a captured variable in a Fn closure"错误。

英文:

I was having trouble understanding the monty hall problem so I put together some Rust. I have a function which determines whether or not a participant wins a game show. If they win the game show then the function returns true, otherwise it returns false. I wanted to test for very large numbers so I added a Rayon Parallel Iterator to the for loop. The code follows:

fn gameshow(num_doors: usize, num_runs: usize, change: bool) -> usize {
	let mut won_games:usize = 0;
	let runs: Vec<Vec<bool>> = vec![stagehand(num_doors); num_runs]; // Creates common solution 
	if change {
		ParallelIterator::for_each(IntoParallelIterator::into_par_iter(runs), |game| {
			let winner: bool = run_game_no_change(game); // Each door is chosen randomly when tested
			if winner { won_games += 1;}
		});
	}
	else {
		ParallelIterator::for_each(IntoParallelIterator::into_par_iter(runs), |game| {
			let winner: bool = run_game_no_change(game); // Each door is chosen randomly when tested
			if winner { won_games += 1;}
		});		
	}
	won_games	
}

When compiling it throws a "Cannot assign to won_games, as it is a captured variable in a Fn closure" error.

答案1

得分: 3

你不能在并行中修改捕获的外部状态,否则可能会发生数据竞争。Rayon专门设计用于防止这种情况。

不要使用for_each,而是使用map将每个bool映射为0或1,然后取其sum

fn gameshow(num_doors: usize, num_runs: usize, change: bool) -> usize {
    let runs: Vec<Vec<bool>> = vec![stagehand(num_doors); num_runs]; // 创建公共解决方案
    let won_games = if change {
        runs.into_par_iter().map(|game| {
            let winner: bool = run_game_no_change(game); // 在测试时每个门都是随机选择的
            if winner { 1 } else { 0 }
        }).sum()
    } else {
        runs.into_par_iter().map(|game| {
            let winner: bool = run_game_no_change(game); // 在测试时每个门都是随机选择的
            if winner { 1 } else { 0 }
        }).sum()    
    };

    won_games   
}
英文:

You can't modify a captured external state in parallel, or you could have data races. Rayon is specifically designed to prevent this.

Instead of for_each, use map to map each bool to 0 or 1, then take the sum of that:

fn gameshow(num_doors: usize, num_runs: usize, change: bool) -&gt; usize {
    let runs: Vec&lt;Vec&lt;bool&gt;&gt; = vec![stagehand(num_doors); num_runs]; // Creates common solution 
    let won_games = if change {
        runs.into_par_iter().map(|game| {
            let winner: bool = run_game_no_change(game); // Each door is chosen randomly when tested
            if winner { 1 } else { 0 }
        }).sum()
    } else {
        runs.into_par_iter().map(|game| {
            let winner: bool = run_game_no_change(game); // Each door is chosen randomly when tested
            if winner { 1 } else { 0 }
        }).sum()    
    };

    won_games   
}

huangapple
  • 本文由 发表于 2023年6月22日 02:23:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76526139.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定