简体   繁体   中英

How to parallelize for-cycle using PLINQ?

I have a task to parallelize iterations using PLINQ. For it I have a function based on for-cycle:

public void PointGenerator(int n, Random rnd)
{
    for (int i = 1; i <= n; i++)
    {
        x = rnd.NextDouble(); 
        y = rnd.NextDouble(); // 
        if (((x - 0.5) * (x - 0.5) + (y - 0.5) * (y - 0.5)) < 0.25)
        {
            N_0++;
        }
    }
}

How can I do it using PLINQ?

You could try like this:

public bool Check(double x, double y)
{
    return ((x - 0.5) * (x - 0.5) + (y - 0.5) * (y - 0.5)) < 0.25;    
}

// ...

N_0 = Enumerable
    .Range(0, n)
    .Select(i => new { X = rnd.NextDouble(), Y = rnd.NextDouble() })
    .AsParallel()
    .Count(p => Check(p.X, p.Y));

As noted by Roman Dvoskin in the comment under the other answer, Random objects are not thread safe:

However, Random objects are not thread safe. If your app calls Random methods from multiple threads, you must use a synchronization object to ensure that only one thread can access the random number generator at a time. If you don't ensure that the Random object is accessed in a thread-safe way, calls to methods that return random numbers return 0.

This problem can be worked around by generating all XY pairs first.

Use Parallel.ForEach method on a range :

var randLock = new object();
Parallel.ForEach(
    Enumerable.Range(1, n)
,   () => { // if you needed the index, you could use i instead of ()
        lock (randLock) {
            x = rnd.NextDouble(); 
            y = rnd.NextDouble();
        }
        if (((x - 0.5) * (x - 0.5) + (y - 0.5) * (y - 0.5)) < 0.25) {
            Interlocked.Increment(ref N_0);
        }
    });

Note the use of Interlocked.Increment instead of N_0++ to avoid concurrency issues. The use of randLock serves the same purpose: according to the documentation, System.Random is not thread-safe.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM