bdeonovic
bdeonovic

Reputation: 4220

C# parallelize loop

I have the following c# code:

        int[] ns = new int[4] { 100, 500, 1000, 5000 };
        int[] ks = new int[5] { 5, 10, 15, 80, 160 };
        int[] rs = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        for(int n = 0; n<ns.Length; n++)
        {
            for(int k = 0; k < ks.Length; k++)
            {
                for (int r = 0; r < rs.Length; r++)
                {
                    RunProg(ns[n], ks[k], rs[r]);
                }
            }
        }

where RunProg takes a relatively substantial amount of time. I would like to parallelize this code. What is the most straight forward way to parallelize this in C#?

I have not tried any method yet. I was trying to decide between the different functionalities available in C#

Upvotes: 1

Views: 534

Answers (3)

user1726343
user1726343

Reputation:

A simple way to parallelize this is to produce a sequence representing all combinations of inputs, then transforming this sequence to a sequence of thread pool tasks representing the result. This final sequence can simply be passed to Task.WhenAll to await the completion of all tasks.

class Program
{
    static void Main(string[] args)
    {
        int[] ns = new int[4] { 100, 500, 1000, 5000 };
        int[] ks = new int[5] { 5, 10, 15, 80, 160 };
        int[] rs = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        var inputs = ns
            .SelectMany(n => ks.Select(k => new { n, k }))
            .SelectMany(x => rs.Select(r => new { x.n, x.k, r }));

        var tasks = inputs.Select(x => Task.Run(() => RunProg(x.n, x.k, x.r)));
        var results = Task.WhenAll(tasks).Result;
    }

    static int RunProg(int n, int k, int r)
    {
        Thread.Sleep(1000);
        return n + k + r;
    }
}

You can also Parallel.ForEach over the inputs collection, as mentioned in the other answers.

Parallel.ForEach(inputs, x => RunProg(x.n, x.k, x.r));

Upvotes: 2

Mafii
Mafii

Reputation: 7425

Use Parallel.For() for the loops: https://msdn.microsoft.com/de-de/library/dd460713(v=vs.110).aspx

This works if the iterations are not dependent on each other.

Upvotes: 0

mm8
mm8

Reputation: 169160

There is a Parallel.For method:

int[] ns = new int[4] { 100, 500, 1000, 5000 };
int[] ks = new int[5] { 5, 10, 15, 80, 160 };
int[] rs = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Parallel.For(0, ns.Length, n =>
{
    Parallel.For(0, ks.Length, k =>
    {
        Parallel.For(0, rs.Length, r =>
        {
            RunProg(ns[n], ks[k], rs[r]);
        });
    });
});

This should work provided that the order in which the RunProg method is called is not important, and that the method itself is thread-safe.

Upvotes: 2

Related Questions