Wpis z mikrobloga

Taki przykład, dlaczego #rustlang jest zajebisty.

Mam sobie obrazek i chcę na każdym pikselu wykonać jakąś operację. Mogę to zrobić np. tak:

for pixel in image.pixels_mut() {
// zrób coś z pikselem
}

Albo, równoważnie:

image.pixels_mut().for_each(|pixel| {
// zrób coś z pikselem
});

Akurat tak się złożyło, że każdy piksel mogę przetworzyć niezależnie od innych. Chciałbym wobec tego wykorzystać pełnię możliwości mojego wielordzeniowego procesora, puścić to na kilku wątkach i przetwarzać piksele równolegle. Jak to mogę zrobić?

Z pomocą przychodzi rayon - crate implementujący dużo ułatwień do zrównoleglania przetwarzania danych. W moim przypadku wystarczy zrobić tyle:

use rayon::prelude::*;
image.pixels_mut().par_bridge().for_each(|pixel| {
// zrób coś z pikselem
});

To wszystko! Piksele będą teraz wrzucane do puli wątków i przetwarzane na tyle równolegle, na ile się da. Użycie procesora przy wykonywaniu - 100% ( ͡° ͜ʖ ͡°)

#programowanie
  • 11
  • Odpowiedz
@SuppressWarnings: A masz w Javie pewność, że Ci dwa wątki nie będą naraz modyfikowały tych samych danych, albo że jeden wątek nie będzie modyfikował tego, co inny czyta? ( ͡° ͜ʖ ͡°)

A w Ruście masz ( ͡° ͜ʖ ͡°) Jak spróbujesz coś takiego odstawić, to kod się nie skompiluje.

Np. załóżmy, że chciałbym zliczać przetworzone piksele:

let mut pixels_count: usize = 0;
  • Odpowiedz
@fizyk20: A sprawdzałeś może wzrost różnicę w czasie wykonywania? Bo jeśli jest to zrobione tak jak myślę, to wątki cały czas się biją o linie w cache'u i taki zabieg wręcz spowalnia program zamiast go przyspieszać (zajmując przy tym 100% procesora)
  • Odpowiedz