生锈的数组元素的并行计算 [英] Parallel computing of array elements in rust

查看:161
本文介绍了生锈的数组元素的并行计算的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新手拉斯特(V1.0.0)和线程编程。
我尝试计算使用阵列B-数组的元素。的b阵列的每个元素可以计算独立于其他(平行)的。

I'm novice to Rust (v1.0.0) and thread-programming. I try to calculate elements of b-array using a-array. Each element of the b-array can be calculated independently of the others (parallel).

extern crate rand;
use rand::Rng;
use std::io;
use std::thread;
use std::sync::{Arc, Mutex};

fn main() {
  let mut a : [u32; 10] = [0; 10];
  let mut b = Arc::new(Mutex::new([0; 10]));
  let mut rng = rand::thread_rng();

  for x in 0..9 {
    a[x] = (rng.gen::<u32>()  % 1000) + 1;
  };

  for x in 0..4 { 
    let b = b.clone(); 
    thread::spawn(move || { let mut b = b.lock().unwrap();
      for y in 0..4 {
        b[x]   += a[y] * a[y*2+1];
        b[x+5] += a[y+1] * a[y*2];
      }
    });
  };

  thread::sleep_ms(1000); 

  for x in 0..a.len() {
    println!("a({0})={1}, b({0})={2}", x, a[x], b[x]);
  };
}

您能帮我:


  1. 如果我使用:让MUT B =弧::新(互斥::新的([U32; 10] = [0; 10])); - >我得到错误悬而未决的名字U32。您的意思是'A'?如何设置数组元素的类型?

  2. 螺纹:: sleep_ms(1000) - 它是如此粗鲁。我怎么能检查所有线程完成?

  3. 我怎样才能找回我的计算B〔i]和/或在最后一节聚集线程计算的B-阵列?现在,我已经得到了错误:不能索引类型的值'的alloc ::弧::弧LT;的std ::同步互斥:: ::互斥&LT; U32; 10&GT;&GT;

  4. 我可以只用一个B-阵列中的存储和发送成线(使用指针)来计算B-阵列的两个元素?

  1. if I use: let mut b = Arc::new(Mutex::new([u32; 10] = [0; 10])); -> I get error unresolved name 'u32'. Did you mean 'a'? How can I set the type of array element ?
  2. thread::sleep_ms(1000) - It is so rudely. How can I check that all thread is finished?
  3. How can I get back my calculated b[i] and/or gather thread-calculated b-arrays in the final one ? Now I've got error: cannot index a value of type 'alloc::arc::Arc<std::sync::mutex::Mutex<[u32; 10]>>'
  4. Can I use only one b-array in memory and send into thread (using pointers) to calculating two elements of b-array?

感谢的解决方案。
工作code是(我已经修改了它的显示问题):


Thank for solutions. Working code is (I've modified it for show problem):

extern crate rand;
use rand::Rng;
use std::thread;
use std::sync::{Arc, Mutex};

fn main() {
  let mut a : [u32; 10000] = [0; 10000];
  let b = Arc::new(Mutex::new([0u32; 10]));
  let mut rng = rand::thread_rng();

  for x in 0..10000 {
    a[x] = (rng.gen::<u32>() % 10) + 1;
  };

  for x in 0..5 {
    let b = b.clone();
    thread::spawn(move || { let mut b = b.lock().unwrap();
      println!("thread {} started", x);
      for y in 0..5000 {
        b[x]   += a[y] * a[y*2+1];
        b[x+5] += a[y+1] * a[y*2];
      };
      b[x] += a[x];
      b[x+5] -= a[x];
    println!("thread {} finished", x);
    });
  };

  thread::sleep_ms(1000);

  for x in 0..10 {
    println!("b({0})={1}", x, b.lock().unwrap()[x]);
  };
}

输出是:

thread 1 started
thread 1 finished
thread 3 started
thread 3 finished
thread 0 started
thread 0 finished
thread 2 started
thread 2 finished
thread 4 started
thread 4 finished
b(0)=149482
...
b(9)=149065

线程处理一步一步的。

Threads are processed step-by-step.

推荐答案

请注意,的clone()电弧法对象没有克隆的数组,只需将其增加的引用计数器的电弧

Note that the clone() method on the Arc object does not "clone" the array, simply it increments the reference counter of the Arc.

我想你问的拉斯特并行处理数据的总体战略。您code锁定每个线程 B 的数组,所以你没有并行处理。

I think you are asking for a general strategy to process data in parallel in Rust. Your code lock the b array in each thread, so you have no parallel processing.

要你将需要整个阵列上的可变访问数组没有锁,但你不能这样做,在安全锈真正的并行处理。

To do real parallel processing you would need a mutable access to the array without a lock on the entire array but you cannot do that in safe Rust.

要做到这一点,你必须使用某种不安全的机制,这样的原始指针。

To do that you have to use some sort of unsafe mechanism, such raw pointers.

这是一个简单的例子来处理(非易变)输入向量成(可变)输出并行向量:

This is a simple example to process a (non mutable) input vector into a (mutable) output vector concurrently:

use std::thread;
use std::sync::Arc;

fn main() {
    let input = Arc::new([1u32, 2, 3, 4]);
    let output = Arc::new([0; 4]);

    let mut handles = Vec::new();

    for t in 0..4 {
        let inp = input.clone();
        let out = output.clone();
        let handle = thread::spawn(move || unsafe {
            let p = (out.as_ptr() as *mut u32).offset(t as isize);

            *p = inp[t] + (t as u32 + 1);
        });

        handles.push(handle);
    }


    for h in handles {
        h.join().unwrap();
    }

    println!("{:?}", output);
}

您仍然需要使用电弧将数据传递到线程,并有适当的生命周期管理。
那么线程里面你需要得到一个可变数据指针( out.as_ptr()作为* MUT U32 ),然后利用在该线程处理的项目偏移方法。

You still need to use Arc to pass data into the threads and to have a proper lifetime management. Then inside the thread you need to get a mutable pointer to the data (out.as_ptr() as *mut u32), then the item processed in that thread using the offset method.

这篇关于生锈的数组元素的并行计算的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆