かみのメモ

コンピュータビジョン・プログラムな話題中心の勉強メモ

Rustのimageのピクセル処理をRayonで並列化する

これ↓を書くときに困ったのでメモ。

github.com

Rustのimageピクセルごとの処理を書くときはenumerate_pixels_mut()を使うらしい。

これにRayonpar_iter_mut()を組み合わせて、処理を並列化してみる。

extern crate image;
extern crate rayon;

use image::{Rgb, RgbImage};
use rayon::prelude::*;

fn gen_img() -> RgbImage {
    let mut img = RgbImage::new(1200, 800);
    img.enumerate_pixels_mut()
        .collect::<Vec<(u32, u32, &mut Rgb<u8>)>>()
        .par_iter_mut()
        .for_each(|(x, y, pixel)| {
            pixel[0] = (255.0 * (*x as f64 / 1200.0)) as u8;
            pixel[1] = (255.0 * (*y as f64 / 1200.0)) as u8;
            pixel[2] = 128;
        });
    img
}

fn main() {
    let img = gen_img();
    img.save("sample.png").unwrap();
}

これで並列化できてるはず。 一応ベンチマークを取ってみる。

iter_mut()のとき

bench:  22,650,690 ns/iter (+/- 2,139,697)

par_iter_mut()のとき

bench:  16,251,080 ns/iter (+/- 1,763,219)

やはりこの程度の軽い処理ではあまり差が出ないようだが、ちゃんと並列演算してくれてるっぽい。


まだIteratorの扱い方を完全に把握できていないので勉強したい。