Search code examples
parallel-processingerlangdistributed-computingdistributed-systemerlang-otp

How can I implement the following loop in Erlang?


I have the following pseudocode:

for ( int i = 0; i < V ; i++ )
{
  for( int j = 0 ; j < V ; j++ )
  {
    if( ( i != j ) && ( tuple {i,j} belong to E ) )
    {
      R[i] := {i,j};
    }
  }
}

I want to parallelise this code using .
How can I achieve the same thing using Erlang? I am new to Erlang...

Edit:

I know that the following code runs both the calls to say/2 concurrently:

-module(pmap).

-export([say/2]).

say(_,0) ->
  io:format("Done ~n");

say(Value,Times) ->
  io:format("Hello ~n"),
  say(Value,Times-1).

start_concurrency(Value1, Value2) ->
  spawn(pmap, say, [Value1, 3]),
  spawn(pmap, say, [Value2, 3]).

However, here we are hardcoding the functions. So, suppose I want to call say 1000 times, do I need to write spawn(pmap, say, [Valuex, 3]) 1000 times? I can use recursion, but won't it be giving a sequential performance?

Edit:

I tried the following code, where I aim to create 3 threads, where each thread wants to run a say function. I want to run these 3 say functions concurrently(Please comment in the box for more clarification):

-module(pmap).

-export([say/1,test/1,start_concurrency/1]).

say(0) ->
  io:format("Done ~n");

say(Times) ->
  io:format("Hello ~p ~n",[Times]),
  say(Times-1).

test(0) ->
  spawn(pmap, say, [3]);

test(Times) ->
  spawn(pmap, say, [3]),
  test(Times-1).

start_concurrency(Times) ->
  test(Times).

Is this code correct?


Solution

  • I want to run these 3 say functions concurrently. Is this code correct?

    You can get rid of your start_concurrency(N) function because it doesn't do anything. Instead, you can call test(N) directly.

    I aim to create 3 threads

    In erlang, you create processes.

    In erlang, indenting is 4 spaces--not 2.

    Don't put blank lines between multiple function clauses for a function definition.

    If you want to see concurrency in action, then there has to be some waiting in the tasks you are running concurrently. For example:

    -module(a).
    -compile(export_all).
    
    say(0) ->
        io:format("Process ~p finished.~n", [self()]);
    say(Times) ->
        timer:sleep(rand:uniform(1000)),  %%perhaps waiting to receive data from an http request
        io:format("Hello ~p from process ~p~n",[Times, self()]),
        say(Times-1).
    
    loop(0) ->
        spawn(a, say, [3]);
    loop(Times) ->
        spawn(a, say, [3]),
        loop(Times-1).
    

    In the shell:

    3> c(a).     
    a.erl:2: Warning: export_all flag enabled - all functions will be exported
    {ok,a}
    
    4> a:loop(3).
    <0.84.0>
    Hello 3 from process <0.82.0>
    Hello 3 from process <0.81.0>
    Hello 2 from process <0.82.0>
    Hello 3 from process <0.83.0>
    Hello 2 from process <0.81.0>
    Hello 3 from process <0.84.0>
    Hello 2 from process <0.83.0>
    Hello 1 from process <0.81.0>
    Process <0.81.0> finished.
    Hello 1 from process <0.82.0>
    Process <0.82.0> finished.
    Hello 2 from process <0.84.0>
    Hello 1 from process <0.83.0>
    Process <0.83.0> finished.
    Hello 1 from process <0.84.0>
    Process <0.84.0> finished.
    
    5>
    

    If there is no random waiting in the tasks that you are running concurrently, then the tasks will complete sequentially:

    -module(a).
    -compile(export_all).
    
    say(0) ->
        io:format("Process ~p finished.~n", [self()]);
    say(Times) ->
        %%timer:sleep(rand:uniform(1000)),
        io:format("Hello ~p from process ~p~n",[Times, self()]),
        say(Times-1).
    
    loop(0) ->
        spawn(a, say, [3]);
    loop(Times) ->
        spawn(a, say, [3]),
        loop(Times-1).
    

    In the shell:

    5> c(a).     
    a.erl:2: Warning: export_all flag enabled - all functions will be exported
    {ok,a}
    
    6> a:loop(3).
    Hello 3 from process <0.91.0>
    Hello 3 from process <0.92.0>
    Hello 3 from process <0.93.0>
    Hello 3 from process <0.94.0>
    <0.94.0>
    Hello 2 from process <0.91.0>
    Hello 2 from process <0.92.0>
    Hello 2 from process <0.93.0>
    Hello 2 from process <0.94.0>
    Hello 1 from process <0.91.0>
    Hello 1 from process <0.92.0>
    Hello 1 from process <0.93.0>
    Hello 1 from process <0.94.0>
    Process <0.91.0> finished.
    Process <0.92.0> finished.
    Process <0.93.0> finished.
    Process <0.94.0> finished.
    
    7> 
    

    When there is no random waiting in the tasks that you are running concurrently, then concurrency provides no benefit.