Rust - 使用 Rayon 进行排列 - 向量内存分配错误

Posted

技术标签:

【中文标题】Rust - 使用 Rayon 进行排列 - 向量内存分配错误【英文标题】:Rust - using Rayon for permutations - vector memory allocation error 【发布时间】:2021-06-08 13:31:42 【问题描述】:

目标:生成数十亿个排列并​​在每个排列上并行运行代码。

尝试:使用 Itertools 将所有排列分配给结果向量,然后使用 rayon 处理每个排列。

最小可重现代码:

use rayon::iter::ParallelIterator;
use rayon::iter::IntoParallelIterator;
use itertools::Itertools;

fn main() 
    let data: Vec<u128> = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19].to_vec();
    let k = 8;
    let vector: Vec<Vec<u128>>

    //Following code should return 29.6 billion permutations
    let _vector = data.into_iter().permutations(k).map_into::<Vec<u128>> 
    ().collect_vec();

    //Following code then processes each permutation using rayon crate
    (vector).into_par_iter().for_each(move |x| further_processing(x));

data 输入向量为16 个元素或更少时,代码运行。对于 24 个元素,返回以下错误:memory allocation of 121898649600 bytes failed error: process didn't exit successfully: target\debug\threads.exe (exit code: 0xc0000409, STATUS_STACK_BUFFER_OVERRUN)

不使用 rayon crate 可以处理 24 个元素,但速度很慢 - 此代码将最后两行替换为:data.into_iter().permutations(k).for_each(move |x| further_processing(x));

所以问题似乎是内存分配给rayon 可以访问的非常大的、不断增长的排列向量。

有没有办法成功地生成这个非常大的排列集供 rayon 访问,更智能的方式直接在输入数据上使用 rayon,或者更合适的并行计算方法来解决这个问题?

【问题讨论】:

【参考方案1】:

我似乎找不到任何并行排列实现,因此您最好的选择可能是使用ParallelBridge 将迭代器转换为并行迭代器。请注意,除非您的处理是密集的,否则您不应该使用它而只使用常规迭代器方法,因为这会增加同步成本。

use rayon::iter::ParallelIterator;
use rayon::iter::ParallelBridge;
use itertools::Itertools;

fn main() 
    let data: Vec<u128> = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19].to_vec();
    let k = 8;

    let data_iter = data.into_iter().permutations(k);

    data_iter.par_bridge().for_each(move |x| further_processing(x));

【讨论】:

感谢您对@Aplet123 的这一见解,非常感谢。

以上是关于Rust - 使用 Rayon 进行排列 - 向量内存分配错误的主要内容,如果未能解决你的问题,请参考以下文章

迭代 Rust 中的结构向量

Rust语言教程 - 数组与向量

Rust 是不是将添加到向量中的单个项目装箱?

是否可以结合 Rayon 和 Faster?

如何在Rust中修改向量的元素?

Rayon 如何防止线程之间使用 RefCell<T>、Cell<T> 和 Rc<T>?