Erlang/OTP Forums

Author Message

<  Erlang  ~  Sum primes in a range concurrently

kevinjq
Posted: Mon Jun 01, 2009 4:09 pm Reply with quote
Joined: 01 Jun 2009 Posts: 3
Hi all, I'm new to Erlang. I'm trying to solve the problem of summing all the prime numbers under 2 million (yes, it's from project euler). Everyone knows the brute-force way takes forever, and it doesn't utilize the multi-core nature of modern computers. So I figure I'll have a try using Erlang's concurrency oriented programming model to solve this.

Basically, I have three actors in my system:
solve -> the entry point of the program
worker -> the process that sums all the prime numbers in a given range (relatively small ~100, which can be computed in a fairly short amount of time)
tallier -> the process that waits for workers to report their result and compute the final tally.

Here's the code for worker:
Code:

worker() ->
    receive
        {TallierPid, L} ->
            [H|_] = L,
            Sum = sum_prime_in_range(L),
            TallierPid ! {self(), H, Sum}
    end.

sum_prime_inrange(List) ->
    lists:sum(lists:filter(fun(X)->mylib:is_prime(X) end, List)).


Tallier:
Code:

tallier(X) ->
    receive
        {_, H, Sum} ->
             Tally = X + Sum,
             io:format(T: Group~p,X=~p~n", [H, X+Sum]),
             tallier(Tally)
    end.


Solver:
Code:

solver(TallierPid, From, To) ->
    case (To - From) of
        SmallRange when SmallRange =< 1000 ->
            List = lists:seq(From, To),
            WorkerPid = spawn(fun worker/0),
            WorkerPid ! {TallierPid, List};
        _ ->
            Mid = mylib:floor((To+From) div 2),
            solver(TallierPid, From, Mid),
            solver(TallierPid, Mid+1, To)
    end.

Basically, solver is a recursive function that splits the range in halves everytime until the range is deemed small enough.

solve:
Code:

solve() ->
    TallierPid = spawn(mymod, tallier, [0]),
    solver(TallierPid, 2, 2000000).


The program runs and it does compute the sum correctly and quickly and the most exciting thing is in the system process manager, both CPU cores are fully utilized. However, for range 2 million, it still seems to take forever to compute. I didn't leave the program to run very long, though, as I was afraid that keeping both cores to run at 100% may be harmful to my CPU.

Any ideas where I may have done wrong?
View user's profile Send private message
kevinjq
Posted: Mon Jun 01, 2009 5:44 pm Reply with quote
Joined: 01 Jun 2009 Posts: 3
I just realized that my is_prime function is too inefficient...I changed the implementation of is_prime function and now adding the primes under 2 million only takes 5 seconds! Whoah!! Just had a first-hand experience with how powerful it is!
View user's profile Send private message
Mazen
Posted: Mon Jun 01, 2009 7:43 pm Reply with quote
User Joined: 20 Jul 2006 Posts: 164 Location: London
Post code if you want Smile

Some of us might be curious of how it is implemented Smile

EDIT: Eeeerr.... English! Smile


Last edited by Mazen on Tue Jun 02, 2009 8:19 am; edited 1 time in total
View user's profile Send private message
kevinjq
Posted: Tue Jun 02, 2009 3:47 am Reply with quote
Joined: 01 Jun 2009 Posts: 3
Mazen wrote:
Post code if you want Smile

Some of might be curious of how it is implemented Smile


I've written a blogpost about it. I'm still quite new to erlang (http://www.dzone.com/links/fast_and_elegant_way_to_sum_primes_in_a_gigantic.html) so maybe someone has a better solution.
View user's profile Send private message

Display posts from previous:  

All times are GMT
Page 1 of 1
This forum is locked: you cannot post, reply to, or edit topics.

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum