Skip to content

Commit

Permalink
Add a short section on ARC
Browse files Browse the repository at this point in the history
  • Loading branch information
Olivier Saut committed May 26, 2013
1 parent 510d0f2 commit dea6677
Showing 1 changed file with 72 additions and 1 deletion.
73 changes: 72 additions & 1 deletion doc/tutorial-tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ let result = ports.foldl(0, |accum, port| *accum + port.recv() );
# fn some_expensive_computation(_i: uint) -> int { 42 }
~~~

## Futures
## Backgrounding computations: Futures
With `extra::future`, rust has a mechanism for requesting a computation and getting the result
later.

Expand Down Expand Up @@ -329,6 +329,77 @@ fn main() {
}
~~~

## Sharing immutable data without copy: ARC

To share immutable data between tasks, a first approach would be to only use pipes as we have seen
previously. A copy of the data to share would then be made for each task. In some cases, this would
add up to a significant amount of wasted memory and would require copying the same data more than
necessary.

To tackle this issue, one can use an Atomically Reference Counted wrapper (`ARC`) as implemented in
the `extra` library of Rust. With an ARC, the data will no longer be copied for each task. The ARC
acts as a reference to the shared data and only this reference is shared and cloned.

Here is a small example showing how to use ARCs. We wish to run concurrently several computations on
a single large vector of floats. Each task needs the full vector to perform its duty.
~~~
use extra::arc::ARC;
fn pnorm(nums: &~[float], p: uint) -> float {
(vec::foldl(0.0, *nums, |a,b| a+(*b).pow(p as float) )).pow(1f / (p as float))
}
fn main() {
let numbers=vec::from_fn(1000000, |_| rand::random::<float>());
println(fmt!("Inf-norm = %?", numbers.max()));
let numbers_arc = ARC(numbers);
for uint::range(1,10) |num| {
let (port, chan) = stream();
chan.send(numbers_arc.clone());
do spawn {
let local_arc : ARC<~[float]> = port.recv();
let task_numbers = local_arc.get();
println(fmt!("%u-norm = %?", num, pnorm(task_numbers, num)));
}
}
}
~~~

The function `pnorm` performs a simple computation on the vector (it computes the sum of its items
at the power given as argument and takes the inverse power of this value). The ARC on the vector is
created by the line
~~~
# use extra::arc::ARC;
# let numbers=vec::from_fn(1000000, |_| rand::random::<float>());
let numbers_arc=ARC(numbers);
~~~
and a clone of it is sent to each task
~~~
# use extra::arc::ARC;
# let numbers=vec::from_fn(1000000, |_| rand::random::<float>());
# let numbers_arc = ARC(numbers);
# let (port, chan) = stream();
chan.send(numbers_arc.clone());
~~~
copying only the wrapper and not its contents.

Each task recovers the underlying data by
~~~
# use extra::arc::ARC;
# let numbers=vec::from_fn(1000000, |_| rand::random::<float>());
# let numbers_arc=ARC(numbers);
# let (port, chan) = stream();
# chan.send(numbers_arc.clone());
# let local_arc : ARC<~[float]> = port.recv();
let task_numbers = local_arc.get();
~~~
and can use it as if it were local.

The `arc` module also implements ARCs around mutable data that are not covered here.

# Handling task failure

Rust has a built-in mechanism for raising exceptions. The `fail!()` macro
Expand Down

5 comments on commit dea6677

@bors
Copy link
Contributor

@bors bors commented on dea6677 May 28, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from graydon
at osaut@dea6677

@bors
Copy link
Contributor

@bors bors commented on dea6677 May 28, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging osaut/rust/tutorial-tasks = dea6677 into auto

@bors
Copy link
Contributor

@bors bors commented on dea6677 May 28, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

osaut/rust/tutorial-tasks = dea6677 merged ok, testing candidate = 6d7d759

@bors
Copy link
Contributor

@bors bors commented on dea6677 May 28, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on dea6677 May 28, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding incoming to auto = 6d7d759

Please sign in to comment.