在 Rust 中对 Rayon 并行化 for 循环中的成功求和

Summing successes inside of a Rayon Parallelized for loop in Rust

提问人:Penultimate Panacea 提问时间:6/22/2023 更新时间:6/22/2023 访问量:68

问:

我很难理解 monty hall 问题,所以我把一些 Rust 放在一起。我有一个功能可以确定参与者是否赢得游戏节目。如果他们赢得了游戏节目,则该函数返回 true,否则返回 false。我想测试非常大的数字,所以我在 for 循环中添加了一个 Rayon 并行迭代器。代码如下:

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   
}

编译时,它会抛出“无法赋值给 ,因为它是闭包中捕获的变量”错误。won_gamesFn

色人造丝

评论


答:

3赞 PitaJ 6/22/2023 #1

您不能并行修改捕获的外部状态,否则可能会有数据争用。人造丝是专门为防止这种情况而设计的。

而不是 ,用于将每个映射到 0 或 1,然后取:for_eachmapboolsum

fn gameshow(num_doors: usize, num_runs: usize, change: bool) -> usize {
    let runs: Vec<Vec<bool>> = 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   
}

评论

0赞 Aleksander Krauze 6/22/2023
或者,您可以使用原子变量。