< 返回版块

Neutron3529 发表于 2020-05-23 14:04

Tags:高性能计算,并行

一个很简单的栗子,比如我们希望计算a=b+c 这里,如果b和c都是数字,我们什么都不需要做

如果栗子复杂一些,b和c是两个含有16777216个元素的1维数组 而我们要算的是for(i=0;i<16777216;i++)a[i]=sin(b[i])+cos(c[i])/2. (或者某些更复杂的运算) 如果我们用脚本语言,比如R,我们可以加载doParallel包,对比较简单的运算(比如上面的栗子)我们可以用

a=sin(b)+cos(c)/2

直接给出计算结果 哪怕对于更加复杂的计算,R也可以用doParallel包进行并行计算

ans=foreach(i=1:500)%dopar%{any_thing_you_want_to_calculate(...)}

我之所以不想用R,最主要的原因是R绞尽脑汁写出来的代码,性能也就比用脚写的C略快一点 C语言进行并行的时候,可以很轻松地借用#pragma omp parallel指令,使用少数修改完成并行

我想问一下,Rust有没有类似的高性能并行计算的语法糖。 毕竟,手写threadpool控制负载平衡这件事对我来说的确不容易,而教程中也未曾提及如何将同一个数组的不同分片以负载均衡的方式分发到各个线程(没记错unsafe可以……但是……)

希望有Rust大神看到这个帖子吧:)

评论区

写评论
作者 Neutron3529 2020-05-23 19:04

对以下内容的回复:

感谢大神引路!

做一下笔记好了:打包多个向量进行运算(https://docs.rs/rayon/1.3.0/rayon/iter/struct.MultiZip.html)

use rayon::prelude::*;

// This will iterate `r` by mutable reference, like `par_iter_mut()`, while
// ranges are all iterated by value like `into_par_iter()`.
// Note that the zipped iterator is only as long as the shortest input.
let mut r = vec![0; 3];
(&mut r, 1..10, 10..100, 100..1000).into_par_iter()
    .for_each(|(r, x, y, z)| *r = x * y + z);

assert_eq!(&r, &[1 * 10 + 100, 2 * 11 + 101, 3 * 12 + 102]);

有了这个,一般计算应该没问题了 就是,这么做似乎没办法配合自动向量化(https://rustcc.cn/article?id=6801bf96-b37e-4859-b2b7-c5a41c17a036) 或许我还应该想想怎么做向量化的部分 毕竟这个crate提供了par_chunks_mut和with_max_len

对以下内容的回复:

我的栗子比较简单,事实可能比这个复杂许多 计算步骤有可能带if/else(导致计算时间并不均匀) 这时候“有几个核就用几个核跑”这句话可能需要额外的负载均衡问题

至于cache运算结果……总觉得并行时候cache是在找不自在……

Dengjianping 2020-05-23 16:54

https://crates.io/crates/rayon

chenwei767 2020-05-23 16:48
这个不是cpu密集型的吗. 有几个核就用几个核跑. 机器多可以分布式的跑. 再一个就是内存如果多, 就把计算过的sin,cos的答案cache住, 避免重复计算.
1 共 3 条评论, 1 页