How to perform multithreading operations on random positions in the same array?

arrays, c#, multithreading, parallel-processing, random

Solution

If your operations are scoped to non-intersecting ranges of elements (like 1-10, 25-40, 100-123) that you can instead of running in parallel for individual elements run operations on separate ranges. If you don't re-allocate array while operations are in progress you will not need any other synchronization.

If you operations change random elements you'd have to work on proper synchronization and may not be able to get any benefits of running code on multiple threads.

Problem

I have a process running lots of tasks on random positions in `Array` and would like to speed this up by the use of multithreading. What it essentially does is to randomize a position in "Array", check its close surroundings for its values and alter the random position values if a few specific conditions are met. Would it be possible to run something like a ``` Parallel.For(0, n, s => { }); ``` loop instead of the while chunk of code shown below to optimize this function, and how would a block of code to do this look like? I've been thinking about using some "busy" property for the chosen elements but that essentially makes the problem more complicated that it might need to be. ``` public void doStuffTothisArray(ref int[,,] Array, ref IGenerator randomGenerator, int loops) { int cc = 0; int sw = 0; do { if (doStuffOnRandomPositions(ref Array, ref randomGenerator)) sw++; //if stuff was made counter if ((cc % (loops / 10)) == 0) Console.Write("{0} % \t", (cc / (loops / 10)) * 10); //some loading info cc++; //count iterations } while (cc < loops); Console.WriteLine("Stuff altered in {0} iterations: {1}", loops, sw); } ``` Post edit: Dividing the array and distributing the work destroys the dynamics of the array, since it needs to be a complete system. Here's a prototype of the dostuff..() ``` public static bool doStuffOnRandomPositions(ref lattice A, ref IGenerator rr) { position firstPos = new position(rr.Next(0, A.n_size),rr.Next(0, A.n_size),rr.Next(0, A.n_size)); position secondPos = randomNeighbour(ref A, firstPos, ref rr); //checks the closest 3d neighbours indexer the lattice //Console.WriteLine("first:[{0},{1},{2}]\nsecond:[{3},{4},{5}]\n", firstPos.x, firstPos.y, firstPos.z, secondPos.x, secondPos.y, secondPos.z); // get values at coordinates bool first = A.latticeArray[firstPos.x, firstPos.y, firstPos.z]; bool second = A.latticeArray[secondPos.x,secondPos.y,secondPos.z]; if (first == second) //don't bother if they are equal states return false; // checks the energies in surroundings for an eventual spin switch int surrBefore = surroundCheck(ref A, firstPos, first) ; // - surroundCheck(ref A, secondPos, second)); int surrAfter = surroundCheck(ref A, firstPos, !first) ; // - surroundCheck(ref A, secondPos, !second)); if (surrAfter < surrBefore) //switch spin states if lower total energy { A.latticeArray[firstPos.x, firstPos.y, firstPos.z] = !first; A.latticeArray[secondPos.x, secondPos.y, secondPos.z] = !second; return true; } else if ((surrAfter == surrBefore) & latticeDistribution(ref rr)) //TEMPORARY { A.latticeArray[firstPos.x, firstPos.y, firstPos.z] = !first; //TEMPORARY A.latticeArray[secondPos.x, secondPos.y, secondPos.z] = !second; //TEMPORARY return true; } else return false; } //FIX SWITCH PROBABILITIES ``` In this, the lattice class is supposed to represent the "array" with its properties incorporated. Example solution code would be very thanksful due to my inxperience with the c# methods.

Original source