1

I have written a program in C# that does a lot of parallel work using different threads. When i reach approx 300 threads the GUI of the program starts to become slow and the execution of threads is also slowing down drastically. The threads are reading and writing data from a mySQL Database runnning on a different machine.

The funny thing is that if i split the work between two processes on the same machine everything runs perfect. Is there a thread limit per process in the .net framework or in windows? Or why am I getting this behaviour? Could it be a network related problem? I am running Windows 7 Ultimate and i have tried both VS2010 and VS 2012 with the same behaviour.

Gray
  • 115,027
  • 24
  • 293
  • 354
Peter
  • 11
  • 1
  • 3

5 Answers5

4

The way processor time is allocated is that the Operating System gives processor time to every process, then every process gives time to every thread. So two processes will get twice the processor time, and that's why it works faster if you divide the program into two processes. If you want to make the GUI run smoother, just set the priority higher for that thread. This way the GUI thread will get more processor time then the other threads, but not so much that it will noticeably slow down the other threads.

Ionut Hulub
  • 6,180
  • 5
  • 26
  • 55
  • Ok, so shouldn't one process be able to utilize all of the systems performance? – Peter Sep 27 '12 at 12:35
  • well.. there are like tens of processes open at a particular time. if there are 19 processes and you open one, you will 1 unit of processor time in 20 units the OS gives because there are 19 other processes that get time. But if you have two processes open then you get 2 units of processor time in 21 units the OS gives, so almost twice the processor time. – Ionut Hulub Sep 27 '12 at 12:38
  • @user1703285 That depends on the process priority. If you have the highest priority (realtime) and for each core you have complete CPU consumtion (for example `while (true) {}`) then yes. But when there's many processes running, and your priority is lower than high, other processes will consume CPU too. – Aidiakapi Sep 27 '12 at 12:39
  • 1
    The OP should also look up the concept of "Context Switching" and the side-effects. More threads does ***not*** always mean better performance. – Brady Sep 27 '12 at 12:41
  • 2
    The fact that it runs better as two processes instead of one isn't explained by this. The GUI thread gets a priority boost whenever it gets a new message; so, artificially increasing the priority might not make a difference. – Peter Ritchie Sep 27 '12 at 12:43
  • The way processor time is allocated is that the Operating System gives processor time to every thread. Some threads may belong to the same process. The unit of execution is a thread, not a process. Unless some process-based CPU quota is being applied, (nad this is not a default on Windows), no-one has yet answered the OP question. – Martin James Sep 27 '12 at 12:55
  • @Brady - the OP has two cases, both with 300 threads. One is bad, the other perfect. – Martin James Sep 27 '12 at 13:01
  • @IonutHulub - I bet that doesn't change much either. The more I look at this , the more I suspect some restriction/config/whatever issue with mySQL. Maybe some per-process connection limit as suggested by Hank. I wish I knew the answer, or even had a better guess that would go some better way to explaining the symptoms, but no:(( – Martin James Sep 27 '12 at 13:21
  • Tried setting thread priority high - no change. Could it be .net network connection limits?? – Peter Sep 27 '12 at 13:37
4

300 threads is silly.

The number of threads should be in the range of your number of cores (2..8) and/or the max simultaneous connections (sometimes only 4 over TCP) your system supports.

Get beyond that and you're only wasting memory, at 1 MB per thread. In a 32bit system, 300 MB is already consuming a lot of the available mem space. And I assume each thread has some buffers attached.

If 2 separate processes perform better than1 then it probably isn't the context switching but either memory usage or a connection limit that holds you back.

H H
  • 263,252
  • 30
  • 330
  • 514
  • Connection limit - maybe. OP symptoms still seem a little strange. One process/300 threads really bad, two processes/150 threads perfect. Strange. – Martin James Sep 27 '12 at 12:59
1

Use ThreadPool. That should automatically allocate the optimal number of threads based on your system by throttling the number of threads in existence. You can also set the maximum number of threads allowable at any one time.

Also, if you're allocating thread to parallelize tasks from within a for-loop, foreach-loop, or linq statment you should look at the Parallel Class or PLINQ.

Joel B
  • 12,082
  • 10
  • 61
  • 69
  • 2
    Using threadpool for long-running threads is not a good idea. The threadpool defaults with a number of active threads that equals the number of cores/processors. As that minimum is unable to be sustained because threads are active the pool starts up one new thread per second to accommodate waiting requests. i.e. it could take a while to run 300. Other parts of the framework and system use the thread pool, using it for long-running threads impacts everything else that uses the pool – Peter Ritchie Sep 27 '12 at 12:41
0

The accepted answer to this question will probably explain what is happening, but 300 threads seems like to many to be a good idea for any normal application.

Community
  • 1
  • 1
codebox
  • 19,927
  • 9
  • 63
  • 81
  • Yes i know it's a bit too many threads. But why does it work when splitting it over two processes? – Peter Sep 27 '12 at 12:35
  • @user1703285, probably because there is much less "Context Switching" with 2 processes than with 300 threads. – Brady Sep 27 '12 at 12:46
  • Eh? Why shoudl it make any difference? One process/300 threads, two processes/150 threads. It's the same number of threads! – Martin James Sep 27 '12 at 12:51
  • @MartinJames Ok, I didnt understand that it was 2 processes with 150 threads each. I understood it was 1 process with 300 threads versus 2 processes, possibly forked with no threads. – Brady Sep 27 '12 at 13:07
  • It is one process with 300 threads vs two processes with 150 threads each. – Peter Sep 27 '12 at 13:11
  • @user1703285 - yes, which is why it's so strange. I've never tried/seen this, so I 'm really curious as to why it's happening, (in case it bites me too:). – Martin James Sep 27 '12 at 13:14
0

At first if you have 300 threads for an application then probably you should rethink about your program design.

Setting up GUI threads priority may give you a better performance of GUI. But if you run so much thread the OS have to allocate space in program stack. And the stack is a continuous segment of the memory. So each time you create a new thread the allocated memory space for the stack may be incapable to hold the new thread. And then the OS must have to allocate a larger continuous space in the memory and copy all the data from the old stack to new stack. So obviously this may cause performance slow of your program.

Debobroto Das
  • 834
  • 6
  • 16
  • The GUI thread gets a priority boost whenever it gets a new message; so, artificially increasing the priority might not make a difference. The GUI thread doesn't do much; the fact that it's sluggish is an indication of a different problem. boosting priority of the GUI thread will likely not have an noticeable effect. – Peter Ritchie Sep 27 '12 at 12:45
  • @Peter, I agree with you. The design of the application should be changed. – Debobroto Das Sep 27 '12 at 12:48
  • ? Every thread has its own stack and the stacks are swappable. A thread that rarely runs will not take up a lot of resources. 300 threads is not unreasonable for some apps, eg. some networked apps. On my system, System has 259 threads, Kaspersky 95 and Sidebar 67. – Martin James Sep 27 '12 at 13:10
  • 300 threads running, each one running MYSQL queries on remote machine. so they should have database connections. I thinks this is not as the same case as yours. – Debobroto Das Sep 27 '12 at 13:32