-2

I made a fake test resembling my real computing task. My current code is:

static void Main()
{
    List<ulong> list = new List<ulong>();
    Action action = () =>
    {
        Random rng = new Random(Guid.NewGuid().GetHashCode());
        ulong i = 0;
        do
        {
            i++;
            if (rng.Next(100000000) == 1000)
            {
                lock (list) list.Add(i);
                Console.WriteLine("ThreadId {0}, step {1}: match is found", 
                                   Thread.CurrentThread.ManagedThreadId, i);
            }
        } while (list.Count < 100);
    };
    int length = Environment.ProcessorCount;
    Action[] actions = new Action[length];
    for (int i = 0; i < length; i++)
        actions[i] = action;
    Parallel.Invoke(actions);

    Console.WriteLine("The process is completed. {0} matches are found. Press any key...", 
                       list.Count);
    Console.ReadKey();
}

Is there any better approach to optimize the number of parallel tasks for one long computing process?

quicktrick
  • 112
  • 1
  • 6
  • You should check out the TPL collections like `ConcurrentBag` rather than `lock`ing a `List` which is unkind to kittens –  Nov 01 '16 at 06:36
  • @MickyD. Please look [here](http://stackoverflow.com/a/29307598/6123485) and try it yourself. I did. – quicktrick Nov 01 '16 at 06:50
  • To those downvoting the OP. If you know a better approach for such a case, please give your answer, instead of downvoting. I've searched the Internet for a very long time before I asked this question. I haven't found any better solution for such a task yet. – quicktrick Nov 01 '16 at 09:05
  • 1
    So? http://stackoverflow.com/a/2951108/585968 and http://stackoverflow.com/a/7193739/585968. You've just been lucky –  Nov 01 '16 at 10:43
  • Lucky in what? I lock the list for writing, so what a problem can I encounter? Its count may change while another thread is reading it? It's not a problem, because each loop will end when the count is greater or equal some value. I don't understand your comment. The locked List works three times faster than ConcurrentBag. Test it yourself. – quicktrick Nov 01 '16 at 11:27
  • _"[Like this cup, you are full of opinions and speculations. To see the light of wisdom... you first must empty your cup](http://www.imdb.com/character/ch0188485/quotes)"_ –  Nov 05 '16 at 12:46

1 Answers1

1

I'm not sure if i understood the question correctly. The code you've shared will run different instances of the action in parallel. But if you like to compute a long running task in parallel for performance, then you should divide the long running task to small work groups Or If the you are iterating over a collection you can use Parallel for or foreach provided by TPL (Task parallel library) which will determine the number of threads depending on metrics like number of cores and load on cpus etc.

Mertus
  • 1,145
  • 11
  • 17
  • 1
    Sorry @Mertus, I can't divide my task to small groups. It is almost exactly like that I gave above. It's one long genetic algorithm of finding best matches. I know about parallel iterating over a collection, but it will reduce performance of my algorithm in total and significantly increase consuming of resources. I've already tried that approach. This one is better, basing on my current tests. – quicktrick Nov 01 '16 at 07:01
  • So you are increasing the probability to find a match sooner by running the same algorithm with different starting points at the same time. If that's the case I think you are right with your approach and TPL wouldn't do any good. – Mertus Nov 01 '16 at 07:06