2

I know this might have been asked in the past but I am an absolute beginner in Julia.

I have a simple code in Julia that I would like to run in parallel.

#--Two Calculations during the Loop--

vt_0=0
ct_0=0

for i=1:10

 #--Calculation vt_1
 vt_1=max(rand(1:i),vt_0,ct_0)


 #--Calculation ct_1
 ct_1=min(rand(1:i),vt_0,ct_0)

 ct_0=ct_1
 vt_0=vt_1

end

So as you can see, the calculation of vt_1 and ct_1 could be done at the same time (or during the same loop without having the ct_1 calculation waiting for the vt_1 calculation).

Can anybody help me modify this code to run in parallel? Should I download any Julia script/library? (I have a much bigger and complicated code for dynamic programing but the essence is the same.)

Thank you in advance

Gunnar
  • 105
  • 5
  • 1
    You might want to change the title as by parallelize a basic loop people would guess you mean each iteration of the loop on a separate core whereas what (I understand) you really want is just to run multiple expressions asynchronously and then wait for all the answers. – Alexander Morley Oct 13 '17 at 12:48
  • Done. Hope it makes more sense now. – Gunnar Oct 13 '17 at 13:04

2 Answers2

3

Is this what you are looking for? Probably faster not to use anonymous function like I have here but other than that.

addprocs(2)        
vt_0 = 0; ct_0 = 0;
for i=1:10
  #--Calculation vt_1
  vt_1 = remotecall((x,y)->max(rand(1:i),x,y), 2, vt_0, ct_0)

  #--Calculation ct_1
  ct_1 = remotecall((x,y)->min(rand(1:i),x,y), 3, vt_0, ct_0)

  ct_0 = fetch(ct_1)
  vt_0 = fetch(vt_1)
end

Or without anonymous funcs:

addprocs(2)
@everywhere minrand(i,x,y) = min(rand(1:i),x,y)
@everywhere maxrand(i,x,y) = max(rand(1:i),x,y)
vt_0 = 0; ct_0 = 0; 

for i=1:10 
  #--Calculation vt_1
  vt_1 = remotecall(maxrand, 2, i, vt_0, ct_0)

  #--Calculation ct_1
  ct_1 = remotecall(minrand, 3, i, vt_0, ct_0)

  ct_0 = fetch(ct_1)
  vt_0 = fetch(vt_1)
end
Alexander Morley
  • 4,111
  • 12
  • 26
  • Exactly what I was looking for! Thanks a lot. – Gunnar Oct 13 '17 at 12:19
  • Hi! I have been trying out these two parallel versions (with different parameters) and the time it takes to calculate in parallel is robustly much longer than sequentially. For example, by changing the number of iteration from 10 to 10000 it takes in my simple sequential code an average of 0.010 seconds to complete, while in the parallel code (the second one you provide actually) it takes an average of 27 seconds to complete. Do you think I am doing something wrong? Perhaps I am missing something? I am using a Jupyter Notebook just in case. TIA! – Gunnar Oct 14 '17 at 19:43
  • So 27 seconds sounds too big so there might be something else there but ... there is always going to be an overhead (IO-related) to sending data to/from another processor which in this case outweighs the gain from splitting the computation. (if you had say 20 expressions that could be split in each loop then the story might be different). You *might* have better luck trying multi-threading - otherwise go with what timing tells you is fastest! – Alexander Morley Oct 16 '17 at 12:12
  • (and or you can ask a separate question about the speed of the above on SO you will likely find someone who knows more than me!) – Alexander Morley Oct 16 '17 at 12:13
  • Thank you! Indeed I found more issues with the dual processing, will save it for other post. – Gunnar Oct 16 '17 at 15:36
2

I'll be curious if there's an actual good answer to this. Normally parallel execution in Julia is part of Base, so you don't need any special library for it. But your use case is not typical for parallel execution IIUC. Normally, a parallel for loop would iterate over calling the same expression with different values - i.e. you would perform the expression related to i = 1 on one core, i = 2 on another, and merge the results. There's a good explanation here: https://docs.julialang.org/en/latest/manual/parallel-computing/#Parallel-Map-and-Loops-1

What you're suggesting is to run different bits of the program (different expressions) on different cores. EDIT: There's a good description of how to do that in Alexander's response.

Michael K. Borregaard
  • 7,864
  • 1
  • 28
  • 35