Explore concurrent programming in Erlang.
Beginning of class session 35.
ErlangHomework folder. Within the folder are a couple of new files that you will use for this homework.
creation.erl.
benchmark/1 function works.
On a Windows box, you do this by editing the shortcut for Erlang. Edit the properties of the shortcut so that the Target is like:
"C:\Program Files\erl5.6.2\bin\werl.exe" +P 250000
Do not change the text between the quotes from what it currently is on your machine. Add the +P 250000 after the closing quote.
+P <limit> option. For example:
$ erl +P 250000
erlang:system_info(process_limit).
Implement a function benchmark/0 to generate a table of benchmark information for N values of 1000, 2000, 5000, 10,000, 20,000, 50,000, 100,000 and 200,000. The table should show the value of N, the “wall clock” time used total and per process, and the processor time used total and per process for each case. See the documentation for the io module for help on the io:format function.
Here’s example output on my machine using just a single core:
CPU Time Clock Time
N Tot (s) Per (ms) Tot (s) Per (ms)
1000 0.000 0.000 0.006 0.006
2000 0.010 0.005 0.010 0.005
5000 0.020 0.004 0.020 0.004
10000 0.030 0.003 0.040 0.004
20000 0.060 0.003 0.078 0.004
50000 0.160 0.003 0.209 0.004
100000 0.320 0.003 0.430 0.004
200000 0.660 0.003 0.935 0.005
On my machine, the CPU time per process when using two cores is nearly 6 times higher than when using a single core. Why might that be? If you have a multicore CPU, you can use the +S n argument to erl or werl to tell Erlang to use n schedulers. Set this to 1 to run Erlang on a single core.
passing.erl.
ring_part_loop/1. You'll be adding several message patterns to the receive block there.
ring_part_loop/1 so it handles a message {new_next, Pid} by passing Pid to the recursive call rather than NextProcessPid as in the _Unknown case.
Write a function spawn_ring(N) (and any necessary helper functions) that spawns N processes using ring_part_loop/1. It should use appropriate arguments or message sends to those processes to configure them in a ring as shown in the figure below. Your spawn_ring(N) should return the process ID of one process in the ring.
Modify ring_part_loop/1 so it handles a message {relay, String, …}, where String is some message text and the … is left for you to decide.
Design your message structure and code so that the relay message is sent around the ring one full loop. When the message returns to the first process in the ring, that process should print the message String.
During the course of relaying the message you may choose to modify the “…” part of the message.
Modify ring_part_loop/1 so the relay message includes a value M like {relay, String, M, …}, where String is again some message text, M is the number of circuits the message should make around the ring, and the … is again left for you to decide.
Modify your message structure and code so that the relay message is sent around the ring M full loops. When the message returns to the originating process after the Mth loop, that process should print the message String and stop relaying the message.
relay message to include an Originator process ID. This originator process ID will belong to some process not in the ring and won't change as the message goes around the loop. In ring_part_loop/1, rather than printing the message String, change your code to send the message back to the originator, like this:
Originator ! String
Turn in your work by committing it to your SVN repository.