Add the LPT algorithm

This commit is contained in:
Rodolphe Bréard 2024-10-30 23:22:44 +01:00
parent b88fdd7665
commit 7fc15efb1a
4 changed files with 39 additions and 1 deletions

View file

@ -65,13 +65,15 @@ algorithms in Rust and benchmark them. Let the battle begin.
- `single thread`: No multi-threading or any optimization of any kind. Used as - `single thread`: No multi-threading or any optimization of any kind. Used as
a reference. a reference.
- `lpt`: Manual multi-threading. Tasks are sorted so the shortest ones are
executed first. This is the [longest-processing-time-first algorithm][lpt].
- `rayon`: Multi-threading provided by the `rayon` crate, but no optimization - `rayon`: Multi-threading provided by the `rayon` crate, but no optimization
of any kind. Used as a reference. of any kind. Used as a reference.
- `rayon sorted`: Multi-threading provided by the `rayon` crate. Tasks are - `rayon sorted`: Multi-threading provided by the `rayon` crate. Tasks are
sorted so the shortest ones are executed first. sorted so the shortest ones are executed first.
- `rayon sorted reverse`: Multi-threading provided by the `rayon` crate. Tasks - `rayon sorted reverse`: Multi-threading provided by the `rayon` crate. Tasks
are sorted so the longest ones are executed first. This should behave as an are sorted so the longest ones are executed first. This should behave as an
[LPT][lpt]. LPT.
- `rayon sorted reverse`: Similar to `rayon sorted reverse`, but tasks are - `rayon sorted reverse`: Similar to `rayon sorted reverse`, but tasks are
sorted from shortest to longest and are then iterated in the reverse order. sorted from shortest to longest and are then iterated in the reverse order.

View file

@ -6,6 +6,7 @@ use rust_job_scheduling::Task;
const TEST_DATA: &[(&str, &[Task])] = &[("10 tasks", T_10), ("500 tasks", T_500)]; const TEST_DATA: &[(&str, &[Task])] = &[("10 tasks", T_10), ("500 tasks", T_500)];
const TEST_FUNCS: &[(&str, &dyn Fn(&[Task]))] = &[ const TEST_FUNCS: &[(&str, &dyn Fn(&[Task]))] = &[
("single thread", &single_thread), ("single thread", &single_thread),
("lpt", &lpt),
("rayon", &rayon), ("rayon", &rayon),
("rayon sorted", &rayon_sorted), ("rayon sorted", &rayon_sorted),
("rayon sorted reverse", &rayon_sorted_reverse), ("rayon sorted reverse", &rayon_sorted_reverse),

View file

@ -1,5 +1,7 @@
mod lpt;
mod rayon; mod rayon;
mod single_thread; mod single_thread;
pub use lpt::lpt;
pub use rayon::*; pub use rayon::*;
pub use single_thread::single_thread; pub use single_thread::single_thread;

33
src/algorithm/lpt.rs Normal file
View file

@ -0,0 +1,33 @@
use crate::Task;
use std::sync::{Arc, Mutex};
use std::thread;
pub fn lpt(data: &[Task]) {
let mut data = data.to_vec();
data.sort();
let data_mt = Arc::new(Mutex::new(data));
let nb_threads = thread::available_parallelism()
.map(|n| n.get())
.unwrap_or(1);
let mut handles = Vec::with_capacity(nb_threads);
for _ in 0..nb_threads {
let dt = data_mt.clone();
let h = thread::spawn(move || loop {
let mut data = dt.lock().unwrap();
let task = match data.pop() {
Some(t) => t,
None => {
break;
}
};
std::mem::drop(data);
task.execute();
});
handles.push(h);
}
for h in handles {
let _ = h.join();
}
}