程序仍然使用par_iter和par_extend在一个线程上运行

时间:2019-07-12 13:26:26

标签: parallel-processing rust iterator rayon

我正在尝试并行化我的代码的一部分,尽管使用了par_iter()和并行迭代器par_extend()i32,但看起来它仍在单个线程上运行。

我只是创建一个collections::HashSet的向量,用很多值填充它,然后将这些值移动到use std::collections::HashSet; fn main() { let my_vec: Vec<i64> = (0..100_000_000).collect(); let mut my_set: HashSet<i64> = HashSet::new(); let st = std::time::Instant::now(); my_set.extend( my_vec.iter().map(|x| x*(x+3)/77+44741) // this is supposed to take a while to compute ); let dur = st.elapsed(); println!("{:?}", dur); } 的整数中。

我的单线程代码:

8.86 s

运行时间平均约为extern crate rayon; use rayon::prelude::*; use std::collections::HashSet; fn main() { let my_vec: Vec<i64> = (0..100_000_000).collect(); let mut my_set: HashSet<i64> = HashSet::new(); let st = std::time::Instant::now(); my_set.par_extend( my_vec.par_iter().map(|x| x*(x+3)/77+44741) // this is supposed to take a while to compute ); let dur = st.elapsed(); println!("{:?}", dur); } 。 这是使用并行迭代器的代码:

8.62 s

“并行”版本的平均运行时间几乎相同(public LayoutInflater inflater; private ArrayList<BrowseHuntSlideModel> dataModelArrayList; Double lat, lng; String address; private boolean hideChkbox = false; public static ArrayList<Object> mySelectPlace = new ArrayList<Object> (); public static ArrayList<String> mySelectPlaceAdd = new ArrayList<> (); public static ArrayList<String> mySelectplaceImg = new ArrayList<> (); public static ArrayList<String> mySelectplaceDesc = new ArrayList<> (); public BrowseHuntSlideAdapter(Context ctx, ArrayList<BrowseHuntSlideModel> dataModelArrayList) { inflater = LayoutInflater.from ( ctx ); this.dataModelArrayList = dataModelArrayList; //this.mapboxMap = mapBoxMap; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = inflater.inflate ( R.layout.browse_slide_list_item, parent, false ); MyViewHolder holder = new MyViewHolder ( view ); return holder; } public void setCheckboxVisibilityStatus(boolean status) { hideChkbox = status; notifyDataSetChanged(); } @Override public void onBindViewHolder(BrowseHuntSlideAdapter.MyViewHolder holder, int position) { if(hideChkbox) holder.checkBox.setVisibility(GONE); //Make it invisible instead of GONE if needed. else holder.checkBox.setVisibility(VISIBLE); } @Override public int getItemCount() { return dataModelArrayList.size (); } class MyViewHolder extends RecyclerView.ViewHolder { TextView place_name, place_address, distance; ImageView place_image; Button button; CheckBox checkBox; public MyViewHolder(View itemView) { super ( itemView ); Context context = itemView.getContext (); checkBox = (CheckBox)itemView.findViewById(R.id.checkbox); //place_address1 = (TextView) itemView.findViewById ( R.id.place_address ); } ),并且CPU监视器清楚地显示单个CPU的工作速度为100%,而其他CPU则等待。

您知道我做错了还是不理解?

1 个答案:

答案 0 :(得分:3)

您的模拟是不正确的,因为您的计算实际上是很快的,是如此之快,以至于它比线程上下文切换要快几个数量级。您的核心可能是人造丝运行时为100%,而其他核心正在等待它。

如果您实际上用睡眠代替了计算,结果将与您预期的一样:

use std::collections::HashSet;
use rayon::prelude::*; // 1.1.0
use std::time::Duration;

fn main() {
    fn slow(i: &i64) -> i64 {
        std::thread::sleep(Duration::from_millis(5));

        *i
    }

    let my_vec: Vec<i64> = (0..100).collect();

    let mut my_set: HashSet<i64> = HashSet::new();

    let st = std::time::Instant::now();
    my_set.extend(
        my_vec.iter().map(slow)  // this is supposed to take a while to compute
    );
    let dur = st.elapsed();
    println!("Regular: {:?}", dur);

    let st = std::time::Instant::now();
    my_set.par_extend(
        my_vec.par_iter().map(slow) // this is supposed to take a while to compute
    );
    let dur = st.elapsed();
    println!("Rayon: {:?}", dur);
}

输出:

Regular: 685.670791ms
Rayon: 316.733253ms

当尝试优化代码时,必须仔细对其进行基准测试,因为有时在并行化代码时,它可能会使速度变慢。