Multicore

Aspects

Speeding up programs on a multicore CPU

General guidelines

Making code run in parallel

code

map(_, []) -> [];
map(F, [H|T]) -> [F(H)|map(F, T)].

Parallel map

pmap(F, Xs) ->
   S = self(),
   Ref = make_ref(),
   Pids = map(fun(X) -> spawn( fun() -> 
                                  S ! {self(), Ref, F(X)} 
                               end )
              end, Xs),
   gather(Pids, Ref).

gather([Pid|T], Ref) -> 
   receive
       {Pid, Ref, Ret} -> [Ret|gather(T, Ref)]
   end ;
gather([], _) -> [].

Workers

code

Implementation of workers

   worker(Compute) ->
       spawn (fun () -> worker_body(Compute) end ).

   worker_body(Compute) ->
            receive {Pid, Tasks} ->
                    Result = Compute(Tasks),
                    Pid ! {self(), Result},
                    worker_body(Compute)
            end.
  

Function pmap using workers

On lock based programming

Software Transactional Memories (STM)

We have two processes with two different transactions.

Transaction 1

Now, both transactions read their corresponding variables. Each transaction recalls the version number of the read variables.

Transaction 2

The transaction on the left firstly writes into variable x, and the transaction on the right follows but it fails (Why?) and retry.

Transaction 3

The transaction on the right retries.

Transaction 4

At the time of writing, it succeeds (Why?). Transaction 5