
Data Parallelism in Rust - KwanEsq
http://smallcultfollowing.com/babysteps/blog/2013/06/11/data-parallelism-in-rust/
======
grayrest
I posted this as a separate submission but Nico posted the followup post [1]
mentioned at the end of the opening paragraph:

> In particular, the existing borrow checker rules, which were aimed at
> preventing dangling pointers, turn out to be extremely well-suited to this
> task. I find this very interesting and very heartening as well, and I think
> it points to a kind of deeper analogy between memory errors in sequential
> programs and data races in parallel programs. I will elaborate on this
> theory in a later post.

[1]
[http://smallcultfollowing.com/babysteps/blog/2013/06/11/on-t...](http://smallcultfollowing.com/babysteps/blog/2013/06/11/on-
the-connection-between-memory-management-and-data-race-freedom/)

------
gtani
here's a preprint of the 3 layer cake article referenced in blog post (Johnson
is, of course, the Gang of 1:

[http://www.upcrc.illinois.edu/workshops/paraplop10/papers/pa...](http://www.upcrc.illinois.edu/workshops/paraplop10/papers/paraplop10_submission_8.pdf)

and also this deck on Go/clojure/scala/erlang for comparison

[http://kachayev.github.io/talks/kharkivpy%230/#/26](http://kachayev.github.io/talks/kharkivpy%230/#/26)

__________

Haven't coded in erlang in a long time, but the phrase "unbounded lifetime of
actors" seems to be the antithesis of how actors are used in erlang and
akka... need to read more about rust

~~~
lambda
Never used akka; but in erlang, actors (processes) are frequently long-lived,
which is what he means by "unbounded lifetime. An erlang process generally
doesn't do a single computation and then join back with the spawning process;
instead, it usually stays alive as long as the resource it is managing is
alive.

For example, in a chat server, you might have one process per user, and one
process per channel; when someone says something, it's passed via TCP to the
user process, which passes it to the channel process, which hands it out to
the other user processes, which send it back to their users. Each of the user
processes and channel process are long lived; they are there to sit around
idle until they need to react to an event, at which point they wake up, do
their work, and go back to sleep until another event comes along.

Fork-join, instead, is about shorter-lived processes, that are treated
essentially as parallel subroutines, and go away as soon as that computation
is done.

Note that both actors and fork-join may be mapped to long-lived hardware
threads, but both are used fairly differently; I see a pretty big distinction
between long-lived Erlang actors and short lived fork-join patterns. And of
course, you can emulate fork-join with actors, but based on the paper you
linked to, it sounds like there might be some efficiency benefits from
treating them differently.

~~~
pron
BTW, Java has an incredible fork-join scheduler (was excellent in Java 7, and
has gotten even better in Java 8), which both Akka[1] and Quasar[2] use for
actor scheduling (and fiber scheduling in Quasar's case).

[1]
[http://doc.akka.io/docs/akka/snapshot/scala/dispatchers.html](http://doc.akka.io/docs/akka/snapshot/scala/dispatchers.html)

[2] [http://blog.paralleluniverse.co/post/49445260575/quasar-
puls...](http://blog.paralleluniverse.co/post/49445260575/quasar-pulsar)

------
comex
Can someone explain to me why it's not possible to have two mutable borrows of
a pointer with overlapping lifetimes? Under what circumstances would this be
unsafe in single-threaded code?

~~~
pcwalton
Iterator invalidation. If we didn't have that rule you could write this:

    
    
        let mut vector = ~[ 1, 2, 3, 4, 5 ];
        for vector.each_mut |x| {
        //                   ^ mutable reference
            for 5.times {
                vector.pop();
        //      ~~~~~^ mutable reference
            }
            println((*x).to_str()); // segfault: invalidated iterator
        }

