From a4050dffc4ff43f66cb8346207f1f42c48244933 Mon Sep 17 00:00:00 2001 From: Orestis Malaspinas <orestis.malaspinas@hesge.ch> Date: Thu, 24 Jan 2019 14:16:55 +0100 Subject: [PATCH] added rayon and clone --- presentation/codes/ex_rayon/Cargo.toml | 8 ++ presentation/codes/ex_rayon/src/main.rs | 26 ++++++ presentation/intro.md | 111 ++++++++++++++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 presentation/codes/ex_rayon/Cargo.toml create mode 100644 presentation/codes/ex_rayon/src/main.rs diff --git a/presentation/codes/ex_rayon/Cargo.toml b/presentation/codes/ex_rayon/Cargo.toml new file mode 100644 index 0000000..138cf63 --- /dev/null +++ b/presentation/codes/ex_rayon/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "ex_rayon" +version = "0.1.0" +authors = ["Orestis Malaspinas <orestis.malaspinas@hesge.ch>"] +edition = "2018" + +[dependencies] +rayon = "1.0" \ No newline at end of file diff --git a/presentation/codes/ex_rayon/src/main.rs b/presentation/codes/ex_rayon/src/main.rs new file mode 100644 index 0000000..58ebf59 --- /dev/null +++ b/presentation/codes/ex_rayon/src/main.rs @@ -0,0 +1,26 @@ +extern crate rayon; + +use rayon::iter::IntoParallelRefIterator; +use rayon::iter::ParallelIterator; + +fn sum_counter(v: &Vec<i32>) -> (i32, i32) { + let mut counter = 0; + // let res = v.iter().map(|&vi| { + let res = v.par_iter().map(|&vi| { + counter += 1; + vi * vi + }).sum(); + (res, counter) + +} + +fn main() { + let v = vec![1, 2, 3, 4, 5, 6, 7, 8]; + + let res: i32 = v.iter().map(|&vi| vi * vi).sum(); + let res: i32 = v.par_iter().map(|&vi| vi * vi).sum(); + + println!("res = {}", res); + + println!("res, counter = {:?}", sum_counter(&v)); +} diff --git a/presentation/intro.md b/presentation/intro.md index 1bd18da..8ed3bb2 100644 --- a/presentation/intro.md +++ b/presentation/intro.md @@ -381,6 +381,63 @@ Garantissent (presque toujours): - En bon Rust ils doivent être rares (4% du code de `rustc`). - Exemple : `raw pointer` +## `raw pointers` (1/2) + +- Créer un `raw pointer` est sûr + +<pre><code data-trim="hljs rust" class="lang-rust"> +fn main() { + let x = 5; + let raw = &x as *const i32; + + let mut y = 10; + let raw_mut = &mut y as *mut i32; +} +</code></pre> + +## `raw pointers` + +- Le déréférencer est dangereux + +<pre><code data-trim="hljs rust" class="lang-rust"> +fn main() { + let x = 5; + let raw = &x as *const i32; + + println!("raw points at {}", *raw); +} +</code></pre> + +# Généricité + +## Traits + +- Interface, classe abstraite, classe virtuelle, ... +- Implémentés pour un type. + +<pre><code data-trim="hljs rust" class="lang-rust"> +trait Clone { // déclaration de l'interface + // &self -> référence du receveur + // Self -> type qui implémente le trait + + fn clone(&self) -> Self; +} + +// T est générique +// on doit donner des contraintes +// on sait que le type implémente Clone +impl<T: Clone> Clone for Vec<T> { + fn clone(&self) -> Self { + let mut v = Vec::new(); + for elem in self { + // elem devient une référence vers chaque élément de self + v.push(elem.clone()); + } + return v; + } +} +</code></pre> + # Fearless concurrency ## Data race @@ -557,9 +614,63 @@ Ce qui se passe en mémoire - Les primitives que nous venons de voir sont les seules disponibles dans la `std`. - Pour "plus": `rayon` ou `crossbeam` par exemple. +## `rayon` (1/2) + +Librairie haut niveau pour faire du parallélisme: + +- Permet de paralléliser automatiquement les itérateurs: `iter`->`par_iter`. + +<pre><code data-trim="hljs rust" class="lang-rust"> +extern crate rayon; + +use rayon::iter::IntoParallelRefIterator; +use rayon::iter::ParallelIterator; + +fn main() { + let v = vec![1, 2, 3, 4, 5, 6, 7, 8]; + + let res: i32 = v.iter().map(|&vi| vi * vi).sum(); + // let res: i32 = v.par_iter().map(|&vi| vi * vi).sum(); + + println!("res = {}", res); +} + +</code></pre> + +## `rayon` (2/2) + +Librairie haut niveau pour faire du parallélisme: + +- Conserve **toutes** les garanties de sécurité! + +<pre><code data-trim="hljs rust" class="lang-rust"> +extern crate rayon; + +use rayon::iter::IntoParallelRefIterator; +use rayon::iter::ParallelIterator; + +fn main() { + let v = vec![1, 2, 3, 4, 5, 6, 7, 8]; + + let mut counter = 0; + let res: i32 = v.iter().map(|&vi| { + counter += 1; + vi * vi + }).sum(); + + // let res: i32 = v.par_iter().map(|&vi| { + // counter += 1; + // vi * vi + // }).sum(); + + println!("res = {}", res); +} +</code></pre> + # Et beaucoup plus - Gestion d'erreurs: `Option`, `Result`. +- Généricité. - Tests ("documentation testing"). - Benchmarks (`nightly only`). - *Hygienic* `macros!`. -- GitLab