#распараллеливание #rust
Хотел поэкспериментировать с параллельностью в Rust, в частности - сравнить последовательный
map из стандартной библиотеки и параллельный map из rayon. Вот код бенчмарка:
#![feature(test)]
extern crate test;
extern crate rand;
extern crate rayon;
#[cfg(test)]
mod tests {
use rayon::prelude::*;
use test::Bencher;
#[bench]
fn iter_test(b: &mut Bencher) {
let vec: Vec = (0..20000).collect();
b.iter(|| -> i64 {
vec.iter().map(|x| x * x).sum()
});
}
#[bench]
fn par_iter_test(b: &mut Bencher) {
let vec: Vec = (0..20000).collect();
b.iter(|| -> i64 {
vec.par_iter().map(|x| x * x).sum()
});
}
}
Результаты:
running 2 tests
test tests::iter_test ... bench: 8,061 ns/iter (+/- 2,606)
test tests::par_iter_test ... bench: 1,915,544 ns/iter (+/- 40,786,648)
Почему параллельный map настолько медленный? Я конечно понимаю, что на распараллеливание
какие-то ресурсы тратятся, но не столько же. Может последовательный map как-то компилятор
оптимизирует? Как тогда написать бенчмарк, на примере которого можно будет почувствовать
преимущество параллельного map?
P. S. Пробовал под передавать в map рекурсивный факториал - результаты отличаются
не так сильно, но последовательный map все равно быстрее.
Ответы
Ответ 1
Потому что накладные расходы на распараллеливание на порядки превышают полезную нагрузку в данном случае. На моей машине (Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz) параллельная версия начинает обгонять на 16 000 000 значений, а на 32 000 000 обгон достигает ~25% и дальше уже сильно не растёт mkpankov@mkpankov-OptiPlex-9020 /tmp/rtest [master *] ± % ➜ cargo bench # 16000000 Compiling rtest v0.1.0 (file:///tmp/rtest) Finished release [optimized] target(s) in 0.70 secs Running target/release/deps/rtest-14d3cc84caf097ae running 2 tests test tests::iter_test ... bench: 8,749,482 ns/iter (+/- 465,264) test tests::par_iter_test ... bench: 7,700,212 ns/iter (+/- 2,354,146) test result: ok. 0 passed; 0 failed; 0 ignored; 2 measured mkpankov@mkpankov-OptiPlex-9020 /tmp/rtest [master *] ± % ➜ cargo bench # 32000000 Compiling rtest v0.1.0 (file:///tmp/rtest) Finished release [optimized] target(s) in 0.70 secs Running target/release/deps/rtest-14d3cc84caf097ae running 2 tests test tests::iter_test ... bench: 17,497,810 ns/iter (+/- 765,301) test tests::par_iter_test ... bench: 13,826,826 ns/iter (+/- 1,615,362) test result: ok. 0 passed; 0 failed; 0 ignored; 2 measured mkpankov@mkpankov-OptiPlex-9020 /tmp/rtest [master *] ± % ➜ cargo bench # 64000000 Compiling rtest v0.1.0 (file:///tmp/rtest) Finished release [optimized] target(s) in 0.71 secs Running target/release/deps/rtest-14d3cc84caf097ae running 2 tests test tests::iter_test ... bench: 34,855,214 ns/iter (+/- 1,047,213) test tests::par_iter_test ... bench: 27,347,082 ns/iter (+/- 236,451) test result: ok. 0 passed; 0 failed; 0 ignored; 2 measured
Комментариев нет:
Отправить комментарий