Why doesn't multithreading in C# reach 100% CPU?

前端 未结 13 1325
眼角桃花
眼角桃花 2021-01-30 22:17

I\'m working on a program that processes many requests, none of them reaching more than 50% of CPU (currently I\'m working on a dual core). So I created a threa

相关标签:
13条回答
  • 2021-01-30 22:43

    Do you have significant locking within your application? If the threads are waiting for each other a lot, that could easily explain it.

    Other than that (and the other answers given), it's very hard to guess, really. A profiler is your friend...

    EDIT: Okay, given the comments below, I think we're onto something:

    The more cpu-costly part of my code is the call of a dll via COM (the same external method is called from all threads).

    Is the COM method running in an STA by any chance? If so, it'll only use one thread, serializing calls. I strongly suspect that's the key to it. It's similar to having a lock around that method call (not quite the same, admittedly).

    0 讨论(0)
  • 2021-01-30 22:44

    So you solved the problem of using a single COM object and now have an IO problem.

    The increased run time for multiple threads is probably because of mixing random IO together, which will slow it all down.

    If the data set will fit into RAM, try to see if you can prefetch it into cache. Perhaps just reading the data, or maybe memory mapping it together with a command to make it available.

    This is why SQL databases will often choose sequential table scan over an index scan on queries you wouldn't expect: it can be much faster to read all of it in order than to read it in random chunks.

    0 讨论(0)
  • 2021-01-30 22:46

    I think I had a similar problem. I was creating multiple threads in c# that ran c++ code through a COM interface. My dual core CPU never reached 100%.

    After reading this post, I almost gave up. Then I tried calling SetApartmentState(ApartmentState.STA) on my Threads.

    After only changing this, the CPU maxed out.

    0 讨论(0)
  • 2021-01-30 22:47

    This isn't an answer really, but have you checked perfmon to see what resources it is using and have you run profilers on the code to see where it is spending time?

    How have you determined that IO or other non CPU resources are not the bottleneck?

    Can you give a brief description of what the threads are doing?

    0 讨论(0)
  • 2021-01-30 22:50

    Are you sure that your tasks require intensive processor activity? Is there any IO processing? This can be the reason for your 50% load.

    Test: Try using only 2 threads and set he affinity of each thread for each Core. Then open task manager and watch the load of both cores.

    0 讨论(0)
  • 2021-01-30 22:51

    The problem is the COM object.

    Most COM objects run in the context of a 'single-threaded apartment'. (You may have seen a [STAThread] annotation on the main method of a .NET application from time to time?)

    Effectively this means that all dispatches to that object are handled by a single thread. Throwing more cores at the problem just gives you more resources that can sit around and wait or do other things in .NET.

    You might want to take a look at this article from Joe Duffy (the head parallel .NET guy at Microsoft) on the topic.

    http://www.bluebytesoftware.com/blog/PermaLink,guid,8c2fed10-75b2-416b-aabc-c18ce8fe2ed4.aspx

    In practice if you have to do a bunch of things against a single COM object like this you are hosed, because .NET will just serialize access patterns internally behind your back. If you can create multiple COM objects and use them then you can resolve the issue because each can be created and accessed from a distinct STA thread. This will work until you hit about 100 STA threads, then things will go wonky. For details, see the article.

    0 讨论(0)
提交回复
热议问题