7heViking
7heViking

Reputation: 7577

Using all cores in pc with c#

*Please note that I am just testing to understand this.

I am trying to use all the cores of my computer with the Parallel.For() method. This is working just fine, but when I am trying the same method with a normal for loop it is going much faster. The parallel method is taking 16 sec and the normal method is only taking 6 sec.

I hope you can tell me what I am doing wrong here.

Updated code

        DateTime parallelStart = new DateTime();
        DateTime parallelFinish = new DateTime();
        DateTime singeStart = new DateTime();
        DateTime singeFinish = new DateTime();
        parallelStart = DateTime.Now;
        int inputData = 0;

        Parallel.For(0, 1000000000, i =>
        {
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
        });

        parallelFinish = DateTime.Now;
        singeStart = DateTime.Now;

        for (int i = 0; i < 1000000000; i++)
        {
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
            inputData = inputData++;
        }

        singeFinish = DateTime.Now;
        MessageBox.Show("Parallel execution time: " + (parallelFinish - parallelStart).Seconds + "\n" +
                        "Singe execution time: " + (singeFinish - singeStart).Seconds);

First code:

DateTime parallelStart = new DateTime();
DateTime parallelFinish = new DateTime();
DateTime singeStart = new DateTime();
DateTime singeFinish = new DateTime();
parallelStart = DateTime.Now;

Parallel.For(0, 2000000000, i =>
{
    var inputData = 0;
});

parallelFinish = DateTime.Now;
singeStart = DateTime.Now;

for (int i = 0; i < 2000000000; i++)
{
    var inputData = 0;
}

singeFinish = DateTime.Now;
MessageBox.Show("Parallel execution time: " + (parallelFinish - parallelStart).Seconds + "\n" + "Singe execution time: " + (singeFinish - singeStart).Seconds);

Upvotes: 4

Views: 7814

Answers (8)

Patrick Karcher
Patrick Karcher

Reputation: 23603

Setting the value of an existing value type on the stack is incredibly, profoundly trivial. The cost of creating and keeping track of the threads would be large compared to this. Adding any complexity to your operation would drastically change your results. Even creating and setting a string variable equal to the appending of two strings would massively increase the work done. Try something more complicated (almost anything will do!) and you'll see the value of the parallel library increase.

Try this:

Parallel.For(0, 2000000000, i =>
{
    var string inputData = "ninjas " + "like " + "taco";
});

Believe it or not, we have added a lot more processing here. (There's multiple strings being created and tossed in the background) This will change your results. And then when you consider that we do vastly more complicated things in these loops, like:

  • data-access
  • disk IO
  • complicated math
  • filtering / ordering / projecting of lists, etc.

, the results will be dramatic in favor of parallelism.

Upvotes: 5

Eric Lippert
Eric Lippert

Reputation: 659964

Well, what's faster: doing no work yourself, or hiring ten guys to each do one tenth of no work?

What you're doing wrong is that your example is completely artificial. The jitter is fully aware that assigning zero to the same local that is unused over and over again is pointless, so it is probably eliminating the work. Even if it is not, that work is trivial. The work of setting up all the threads is larger than just doing the work yourself.

Do a real test -- do some raytracing or generate a fractal or something in there. Do something realistic that will take minutes or hours on one thread. You cannot reasonably expect to see a savings on a job that is too easy.

Upvotes: 14

Giovanni Galbo
Giovanni Galbo

Reputation: 13081

As most books on parallel programming will mention, "always measure performance." Don't assume that going parallel is faster than using a straight forward loop, because parallelism includes overhead.

You really need to consider how much data needs to be processed, the level of concurrency and and how much sharing of volatile data needs to occur (how much locking is required).

Upvotes: 1

Myles McDonnell
Myles McDonnell

Reputation: 13335

I suspect, without empirical evidence of my own, that the overhead of queuing the additional thread outweights the benefit. What you are asking for is 2bn pieces of work to be executed concurrently, which without checking I suspect Parallel queues with the ThreadPool.

Upvotes: 0

Emond
Emond

Reputation: 50672

Use TotalSeconds instead of Seconds when measuring time.

Upvotes: 0

Mike Nakis
Mike Nakis

Reputation: 61969

Parallelization of code involves a fairly large overhead, and you are using it to perform trivial operations. That's why your code runs very slowly. You will only see an improvement once you flesh-in your code, and your code does plenty of CPU-intensive operations.

Upvotes: 2

crashmstr
crashmstr

Reputation: 28563

Multithreading has overhead. For operations that take a long time compared to the time taken to set up the thread, great.

But in your case, you have a very simple loop body, and the overhead of creating the threads to do the work is outweighing the benefit of doing it in parallel.

Upvotes: 2

Eric Petroelje
Eric Petroelje

Reputation: 60508

This is probably because the overhead of creating the threads and the contention between them takes more time than the operation itself. Try putting something more complex inside that loop and I'd bet your results will change.

Upvotes: 10

Related Questions