1

I was surprised that Parallel doesn't consume all threads. I write this code:

public static long Sum(this IList<long> list)
{
    long result = 0;
    Parallel.ForEach(Partitioner.Create(0, list.Count),
        () => 0L,
        (range, state, sum) => Sum(list, range),
        x =>
        {
            Interlocked.Add(ref result, x);
        });
    return result;
}

then I try to use this one:

long res = list.AsParallel().Sum();

but it consume single core too.

Question: how can I force to run this code in multiple threads, by setting process affinity or something else, I guess, there is some technique to do it.

VMAtm
  • 27,943
  • 17
  • 79
  • 125
Alex Zhukovskiy
  • 9,565
  • 11
  • 75
  • 151
  • try it without the partitioner? – Ewan Apr 14 '15 at 09:35
  • 1
    I'd say summing up a list of long is something you should parallelize in the first place... you get additional overhead per thread created... also a thread != a core... a core can / and does run a lot of threads... try a much bigger list... – Florian Schmidinger Apr 14 '15 at 09:37
  • How did you know it just uses single core? I just tried `Enumerable.Range(1,int.MaxValue).AsParallel().Count();` it uses all of the cores (8 in my case). – Sriram Sakthivel Apr 14 '15 at 09:40
  • 7
    Since you're synchronizing on every 'add' you are killing the performance anyway. Also - I've just tried summing the biggest list I could create in memory, and it took 40ms - without any parallelism - is this worth doing? – Dave Bish Apr 14 '15 at 09:47
  • @DaveBish I tried to do it parallel and could not get faster – Florian Schmidinger Apr 14 '15 at 09:49
  • 1
    Theres just not enough beef in the task to get parallelism to improve performance... – Florian Schmidinger Apr 14 '15 at 09:51
  • @DaveBish where do you see synchronizing on every 'add'? `Interlocked` is only used in `finally` block... – Alex Zhukovskiy Apr 14 '15 at 09:55
  • @SriramSakthivel I opened task manager and saw only one core 100% load – Alex Zhukovskiy Apr 14 '15 at 09:59
  • @AlexZhukovskiy - Quite right - my mistake. Regardless - I don't think this is a great case for parallelism - as the overheads of doing such, are probably greater that the operation itself – Dave Bish Apr 14 '15 at 09:59
  • @DaveBish well, I get same results, multithreading overhead eats all benefits from parallelism, but I believe it's because it doesn't consume enough threads. I know that performance is not a big problem here, but anyway info about forcing execution be done on all cores should be helpful while implementing others LINQ methods. So this is 2 main reasons why I want to make it work faster. – Alex Zhukovskiy Apr 14 '15 at 10:06
  • 1
    They key point is that using 'Task' based Parallelism never guarantees multi-thread execution - it just allows it, based upon internal framework rules. If you ever *need* to have multi-core work done, you are best-off using the 'Thread' object, https://msdn.microsoft.com/en-us/library/aa645740%28v=vs.71%29.aspx – Dave Bish Apr 14 '15 at 10:10
  • This is a default behaviour for `Parallel` class, as there is no direct connction between active threads and performance. – VMAtm Apr 14 '15 at 10:20
  • See also: [1000 threads](http://stackoverflow.com/q/1114317/213550), [Parallel Loops](https://msdn.microsoft.com/en-us/library/ff963552.aspx) – VMAtm Apr 14 '15 at 10:21
  • @DaveBish and It's pretty curious that people upvote your comment about `killing the performance` without examining if it's true or not. And that question is marked as duplicate when it isn't, while "why he isn't running" is not equals to "how to force it running". I only hope that CLR knows situation better than me and additional threads won't speed up the code. – Alex Zhukovskiy Apr 14 '15 at 14:12
  • Not *strictly* a duplicate, I suppose, but close enough IMO. The literal answer to this question is "you can't" which is not very interesting. – Harry Johnston Apr 15 '15 at 01:36

0 Answers0