Цель: сгенерировать несколько миллиардов перестановок и запустить код для каждой из них параллельно.
Попытка: используйте 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)
Без использования ящика вискозы работает с 24 элементами, но очень медленно — этот код заменяет последние две строки на: data.into_iter().permutations(k).for_each(move |x| further_processing(x));
Таким образом, проблема заключается в выделении памяти для очень большого растущего вектора перестановок, к которому затем может получить доступ rayon
.
Есть ли способ либо успешно сгенерировать этот очень большой набор перестановок для доступа к rayon, либо более разумный способ использовать rayon непосредственно во входных данных, либо более подходящий подход параллельных вычислений к этой проблеме?