parallel processing - Procesando vec en paralelo: ¿cómo hacer de forma segura, o sin usar características inestables?
parallel-processing rust (1)
Tengo un vector masivo que quiero cargar / actuar en paralelo, por ejemplo, cargar los primeros cien mil índices en un hilo, luego en otro y así sucesivamente. Como esta va a ser una parte muy caliente del código, he llegado a esta siguiente prueba de concepto de código inseguro para hacer esto sin Arcs y Mutexes:
let mut data:Vec<u32> = vec![1u32, 2, 3];
let head = data.as_mut_ptr();
let mut guards = (0..3).map(|i|
unsafe {
let mut target = std::ptr::Unique::new(head.offset(i));
let guard = spawn(move || {
std::ptr::write(target.get_mut(), 10 + i as u32);
});
guard
});
¿Hay algo que he perdido aquí que pueda hacer que esto explote potencialmente?
Esto usa #![feature(unique)]
así que no veo cómo usar esto en stable. ¿Hay alguna forma de hacer este tipo de cosas en forma estable (idealmente sin usar punteros crudos y sobrecarga de Arc
y Mutex
)?
Además, mirando la documentación de Unique
, dice
También implica que el referente del puntero no se debe modificar sin una ruta única a la referencia
Unique
No tengo claro qué significa "camino único".
Uno puede usar una biblioteca externa para esto, por ejemplo simple_parallel
(descargo de responsabilidad, lo escribí) le permite a uno escribir:
extern crate simple_parallel;
let mut data = vec![1u32, 2, 3, 4, 5];
let mut pool = simple_parallel::Pool::new(4);
pool.for_(data.chunks_mut(3), |target| {
// do stuff with `target`
})
Los métodos chunks
y chunks_mut
son la forma perfecta de dividir un vector / fragmento de T
en trozos de igual tamaño: respectivamente devuelven un iterador sobre los elementos de tipo &[T]
y &mut [T]
.