memory - Rust - 使用 Rayon 进行排列 - 向量内存分配错误
问题描述
目标:生成数十亿个排列并在每个排列上并行运行代码。
尝试:使用 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 的方法,或者更合适的并行计算方法来解决这个问题?
解决方案
我似乎找不到任何并行排列实现,所以你最好的选择可能是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));
}
推荐阅读
- sql - HiveSQL - Erorr mismatched input 'as' expecting
- vba - 在 VBA 中测试位
- python - 如何在 QLCDNumber 屏幕上显示多个数字?
- batch-file - FFMPEG 转换没有原始文件扩展名的文件输出
- filter - v-select 停用某些项目/选项
- eclipse - 如何在 Ecipe 的“声明”选项卡中找到给定的文本?
- eclipse - Eclipse 锁定执行,因此它不会被意外终止
- date - 在谷歌日历上设置动态日期
- reactjs - 带有 useSelector 的无限循环 useEffect
- bash - 我无法执行直到昨天才起作用的命令