On 17 May, 13:37, jer...@martinfamily.freeserve.co.uk wrote: > On 17 May, 13:05, jer...@martinfamily.freeserve.co.uk wrote:> From a user > point of view I think that adding a 'par' construct to > > Python for parallel loops would add a lot of power and simplicity, > > e.g. > > > par i in list: > > updatePartition(i) > > ...actually, thinking about this further, I think it would be good to > add a 'sync' keyword which causes a thread rendezvous within a > parallel loop. This would allow parallel loops to run for longer in > certain circumstances without having the overhead of stopping and > restarting all the threads, e.g. > > par i in list: > for j in iterations: > updatePartion(i) > sync > commitBoundaryValues(i) > sync > > This example is a typical iteration over a grid, e.g. finite elements, > calculation, where the boundary values need to be read by neighbouring > partitions before they are updated. It assumes that the new values of > the boundary values are stored in temporary variables until they can > be safely updated. > > Jeremy
I have coded up a (slightly) more realistic example. Here is a code to implement the numerical solution to Laplace's equation, which can calculate the values of a potential field across a rectangular region given fixed boundary values: xmax = 200 ymax = 200 niterations = 200 # Initialisation old=[[0.0 for y in range(ymax)] for x in range(xmax)] for x in range(xmax): old[x][0] = 1.0 for y in range(ymax): old[0][y] = 1.0 new=[[old[x][y] for y in range(ymax)] for x in range(xmax)] # Iterations for i in range(1,100): print "Iteration: ", i for x in range(1,ymax-1): for y in range(1, xmax-1): new[x][y] = \ 0.25*(old[x-1][y] + old[x+1][y] + old[x][y-1] + old[x-1][y]) # Swap over the new and old storage arrays tmp = old old = new new = tmp # Print results for y in range(ymax): for x in range(xmax): print str(old[x][y]).rjust(7), print In order to parallelise this with the par construct would require a single alteration to the iteration section: for i in range(1,100): print "Iteration: ", i par x in range(1,ymax-1): for y in range(1, xmax-1): new[x][y] = \ 0.25*(old[x-1][y] + old[x+1][y] + old[x][y-1] + old[x-1][y]) # Swap over the new and old storage arrays tmp = old old = new new = tmp The par command tells python that it may choose to fire up multiple threads and automatically partition the data between them. So, for instance, if there were ten threads created each one would work on a sub-range of x values: thread 1 takes x from 1 to 100, thread 2 takes x from 101 to 200, etc. However with this approach there is an overhead in each iteration of starting up the threads and shutting them down again. Depending on the impact of this overhead, it might be better to keep the threads running between iterations by modifying the code like this, adding a 'sync' command to synchronise the threads at the end of each iteration and also making sure that only one of the threads performs the swap of the data arrays. par x in range(1,ymax-1): for i in range(1,100): if __thread__ == 0: print "Iteration: ", i for y in range(1, xmax-1): new[x][y] = \ 0.25*(old[x-1][y] + old[x+1][y] + old[x][y-1] + old[x-1][y]) # Swap over the new and old storage arrays sync if __thread__ == 0: tmp = old old = new new = tmp sync Jeremy -- http://mail.python.org/mailman/listinfo/python-list