Basically I'm working on this beat detection algorithm, the strange thing i am encountering right now is that when i split the work load on to another thread. So now i have one main thread and another worker thread. My worker thread somehow is always working faster than the main thread. It seems strange because what i have learned is that the main thread should theoretically always be faster because it is not taking time to initialise the thread. However what i get is even i pass a extra 1024 samples to the worker thread( they are both working with around 30 million samples currently) it is still faster than the main thread. Is it because i have applications running on my main thread? I'm really confused right now. here is the code
UnityEngine.Debug.Log ("T800 Start");
Step3 s1= new Step3();
Step3WOMT s2= new Step3WOMT();
System.Object tempObj= samples2 as System.Object;
float[] tempArray = new float[eS.Length/ 2];
System.Threading.ParameterizedThreadStart parameterizedts = new System.Threading.ParameterizedThreadStart(s1.DoStep3);
System.Threading.Thread T1 = new System.Threading.Thread(parameterizedts);
T1.Start (tempObj);
s2.DoStep3(samples1);
UnityEngine.Debug.Log ("s2");
//UnityEngine.Debug.Log (stopwatch.ElapsedMilliseconds);
T1.Join();
Don't worry I'm only using c# features in the multithread so I believe it should be fine. What i am really confused about is that if i comment out the T1.join(); line the whole thing somehow go even slower. Im genuinely confused right now as there seems no reasonable answer to this question.
T1.join() does all the magic. It allow main thread to wait till all the worker threads are complete. Is that necessary ? depends on ur application. it is expected for a main thread to wait for the end of execution of its worker threads.
Your system must have multiple cores.
It's possible that Thread.Start can return not immediately after the thread is initialized. Anyway you should use ThreadPool.EnqueueUserWorkItem and ManualResetEvent to wait instead of join.
To see real results your samples count must be big enough so that thread initialization time is minimal compared to the execution time of your code. ThreadPool often doesn't have to initialize a new thread but it still takes some time to launch your code. I think you should not use multithreading for tasks which takes <~50ms.
If you compare the execution time for big samples count (takes few seconds) you'll see that there is no difference in the performance of the main thread and the background one (unless the main thread have higher priority).
Related
I want to start a background thread on some user event, in which I wait/sleep 10 seconds to do something if a variable changes between the time it was passed in and the time it is checked. However, during that 10 seconds, the same user event can repeat, and I want to interrupt & reset the thread to use the new variable and start back at 10 seconds.
For example,
private static int index = 0;
private static Thread myThread = null;
if(myThread != null && myThread.IsAlive) {
// need to 'restart' the thread with updated index
/* Suspend? Resume? */
} else {
// create a new thread and start countdown
myThread = new Thread(new ThreadStart( some_Thread(index) ));
myThread.Start();
}
I read that suspend() and resume() are antiquated, and I've read up some posts on Auto/ManualResetEvent, but they're not exactly what I'm looking for. It's probably something closer to Abort() then Start() a new one, but apparently that's unwise.
So any suggestions how to achieve this with one static thread handle? Again, the 10 seconds 'sleep' has to be interruptible and, thereafter, the thread be discardable or restartable. Thanks!
I want to start a background thread on some user event,
You are doing what we at SO call an "XY problem". You have a completely wrong idea about how to solve a problem and you are asking questions about how to make that wrong way work. Instead, concentrate on the user focussed problem you really have and ask about that.
in which I wait/sleep 10 seconds to do something if a variable changes between the time it was passed in and the time it is checked.
Don't do any of this stuff. If you're making a thread whose job it is to sleep, odds are good that you are doing something very, very wrong. Threads are expensive; only make a thread if you're going to be scheduling a CPU to service that thread.
When you are considering making a thread, ask yourself "would I hire a worker to do this task?" Ten seconds of computer time is ten billion nanoseconds; that's like hiring a worker and paying them to sleep for centuries. You'd never do that; you'd just put "do this later" on your to-do list, and come back to it later. If it gets cancelled, you'd take it off your to-do list.
What you want to do instead is make zero extra threads. Make a cancellable asynchronous workflow that awaits a Task.Delay before it does the work that must be done ten seconds later. If the user event happens during the delay then cancel the workflow and start a new workflow.
If the work that follows the delay is CPU intensive, then schedule a worker thread and await the result. If it is not -- if it is CPU work that comes back in say 30 ms or less -- then just run the work on the main thread. If it is IO gated, then use the asynchronous version of the IO API to stay on the main thread. You want to be making as few threads as you can get away with here.
Be careful. Even though everything is still on one thread, there are still race conditions that are possible in cancellable workflows like this. You still need to consider all possible interleavings of the non-dependent parts of your asynchronous workflows.
In my C#/.NET 3.5 program I am using Threadpool threads ( delegate+BeginInvoke/EndInvoke) to parallelize and speed up some file loading. SystemInternals tool ProcessExplorer shows that number of threads in process is increasing over time, while I would expect to stay the same. Looks like some Threads/Threads handles stay hanging around for no reason.
Interestingly enough, I can not find pattern how threads grow and seems that happen sporadically, without repeatable pattern each time I start application. I spend some time analyzing and here are some observations:
1) code looks like this:
ArrayList IAsyncResult_s = new ArrayList();
AsyncProcessing thread1 = processRasterLayer;
... ArrayList filesToRender....
foreach (string FileName in filesToRender)
{
string fileName2 = FileName;
GeoImage partialImage1;
IAsyncResult asyncResult = thread1.BeginInvoke(
fileName2, .....,
out partialImage1, ..., null, null);
IAsyncResult_s.Add(asyncResult);
asyncResult = null;
}
.................
//block and render all
foreach (IAsyncResult asyncResult in IAsyncResult_s)
{
GeoImage partialImage1;
thread1.EndInvoke(
out partialImage1, , asyncResult);
//render image.. some calls to render partial image here
partialImage1.Dispose();
partialImage1 = null;
}
IAsyncResult_s.Clear();
IAsyncResult_s = null;
thread1 = null;
2) Number of Process Threads
My trace shows that during execution inside loop, ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads); gives numbers like 493, 1000.
At the end of loops , , ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads); gives numbers 500, 1000. So, number of available thread returns to same
Number of process threads reported by SystemInternals ProcessExplorer and API System.Diagnostics.Process.GetCurrentProcess().Threads.Count is the 16 before loops, and around 21 after loops.
If I call againg those loops, number of threads in process grows, but not by fixed nubmer each time, but grows 1-4 each time I repeat above code, so grows like 16->21->22->26->31...
3)Forced garbage collection didn’t htelp
I tried to froce garbage collection to get rid of those extra threads, but that didn’t removed them from process.
4)Profling tools
I was using RedGates Memory and Performace profilers, but hasen’t found obvious reason. I saw several extra threas and their object (ThreadContext etc) hanging, but saw no object holding those threads in memory. I am prety sure those extra threads were involved into loops work above, since I added thread name inside calls, and they still have that name I gave them.
5) Intelitrace
Intelitrace debuging showed also extra threads hanging. They still have names I gave them. But interestingly, it also showed that same thread that is hanging now, was used by above loop in the past, but also same thread was executing some timer related evens from timers form my code.
6) Locating issue
So, When I disable above loops that process filse Asynchroniously, and load files sequentialy, I do not have extra threads, and number of threads in my application is constant and and around 16.
7) Regarding SetMaxThreads :Here how it looks on my machine (XP, .NET 3.5):
Code like this:
ThreadPool.GetAvailableThreads(out AvailableWorkerThreads, out AvailableCompletionPortThreads);
ThreadPool.GetMaxThreads(out MaxWorkerThreads, out MaxCompletionPortThreads);
ThreadPool.GetMinThreads(out MinWorkerThreads, out MinCompletionPortThreads);
Gives result:
MinWorkerThreads:2 MaxWorkerThreads:500 MinCompletionPortThreads:2 MaxCompletionPortThreads:1000 AvailableWorkerThreads:500 AvailableCompletionPortThreads:1000
My app is using maybe 8 worker threads at the same time. I see no problem with SetMaxThreads.
8)
Functionally, I have no problems so far with this solution above. But somehow, if tools report that number of threads in my app is growing, it looks like “resource leak” of some kind, and I would like to address it. It looks like some thread handles are hanging around for no reason.
9) Here is one interesting article. It sasy that thread resources are cleaned once EndInvoke is called. I am doing so in my code. Article sasy: ..”. Because EndInvoke cleans up after the spawned thread, you must make sure that an EndInvoke is called for each BeginInvoke.” “If the thread pool thread has exited, EndInvoke does the following: It cleans up the exited thread's loose ends and disposes of its resources.” See: http://en.csharp-online.net/Asynchronous_Programming%E2%80%94BeginInvoke_EndInvoke
10) Another interesting article. Author says he had thread handle leaks because he was creating controls from non-gui thread. It is pretty elaborate article, see: http://msmvps.com/blogs/senthil/archive/2008/05/29/the-case-of-the-leaking-thread-handles.aspx
11) Another interesting article. It talks about ThreadPool.SetMinThreads property. It seems that it is not ThreadPool.SetMaxThreads but ThreadPool.SetMinThreads that enables useful control over ThradPool. This article is an eye-opener for me, and made me think about how ThreadPool works and performance problems it might cause. Article is: http_://www.dotnetperls.com/threadpool-setminthreads . Anoter similar one is : http_://www.codeproject.com/Articles/3813/NET-s-ThreadPool-Class-Behind-The-Scenes
12) Another interesting article. It is talking about throttling issue with ThreadPool. Article mentions ThreadPool limit of 2 new threads per second increase. See http_://social. msdn. microsoft. com/forums/en-US/clr/thread/3325cb32-371b-4f3e-965f-6ca88538dc3e/
13) So, in maybe 30 tests I saw only 2 times that number of threads allocated would shrink. But, it did happen. I saw once thread number going like 16->....->31->61-> ->30->16. So, it went back to 16. It doesn’t happen often, and it is not about time waited, it was like big activity in process, followed by a period of constant low level activity.
14) ThreadPool.SetMinThreads Method documentation. It talks about 2 new threads per second limit for threadpool. It is not clear if setting this property would remove that limit. http_://msdn.microsoft. com/en-ca/library/system. threading.threadpool.setminthreads(v=vs.90).aspx
So the answer is: there's no leak here. This is how the thread pool works. It keeps around threads that finished working so you don't have to pay the price of thread creation next time you need one. If you have many concurrent work items then the number of threads in the pool will increase but they'll max out at MaxWorkerThreads. (And it has nothing to do with the garbage collector.)
See this article for more info:
http://msdn.microsoft.com/en-us/library/0ka9477y.aspx
i would consider a consumer producer pattern. the idea behind a threadpool is to recycle threads, not create hundreds of new. in best case you have for each cpu one thread, and queue the work. this will be sure faster as you avoid useless context switches and waits for creating new threads, as far as i remember the net threadpool waits about one second until a new thread is created, to give other threads a chance to get recycled.
I heard there is limitation when using waitall on multiple threads (# of threads to wait?). Can anyone give details?
I think the restriction you are referring to is not on the number of threads; it is on the number of handles being waited on. From the MSDN page for WaitHandle.WaitAll(WaitHandle[]):
On some implementations, if more than
64 handles are passed, a
NotSupportedException is thrown.
On the rare occasion that this issue has cropped, I have normally worked around it with:
WaitHandle[] handles = ...
foreach(var waitHandle in handles)
waitHandle.WaitOne();
For completeness, the other restrictions appear to be:
If the array contains duplicates, the
call fails with a
DuplicateWaitObjectException.
The WaitAll method is not supported on
threads that have STAThreadAttribute.
Are you thinking of the STA (single-threaded apartment) limitation of a winform app?
If so, I handle this by simply checking if the 'work queue' is empty after each thread has done it's processing, and calling .WaitOne() on a single ManualResetEvent object that the main thread owns instead of using .WaitAll() at all.
Like this:
moSolverEvent = new ManualResetEvent(false);
ProcessResult(new SolverWorkInProgress());
//Wait here until the last background thread reports in
moSolverEvent.WaitOne();
And then the worker threads are doing this:
if (mhSolverWorkQueue.Count == 0) moSolverEvent.Set();
It works spectacularly well, and avoids any issues with WaitAll(), even in a WinForms app. After all, you're not really waiting for the threads to be done... you're waiting for the WORK to be done. :-)
Just be sure to do the appropriate locking on each of these objects so your threads don't step all over each other.
I have a game in XNA which needs to do network calls. In the update method I determine what needs to be sent and then add it to a list of stuff to send. Then I run the network call. This slows down the application alot obviously. So I first tried creating a new thread like this in the update to make it do it on a seperate thread:
Thread thread;
thread = new Thread(
new ThreadStart(DoNetworkThing));
thread.Start();
I presume creating threads has overhead etc which results in this being even slower.
Finally, I made a method that has while(true){DoNetworkThing();} in it which will keep looping round and run the network call over and over again(it does check if its already busy with one, and whether there is stuff to send). That method I called in the LoadContent method in a thread, so it will run alongside the game in its own thread.
But that is really slow too.
So what am I doing wrong? What is the best way of doing this?
Thanks
I had this exact problem when initially attempting to use threads on XNA -- adding a thread slowed everything down. It turned out that thread affinity was the issue.
On Xbox 360, by default, all threads run on the same processor core; this behaviour differs from Windows, where the kernel places threads onto other cores for you. (See answers on this thread at MSDN social for detail.)
To get around it, you need to set the affinity for your thread to another core in your thread function:
void DoNetworkThing()
{
#ifdef XBOX
Thread.SetProcessorAffinity(3); // see note below
#endif
/* your code goes here */
}
Thread thread = new Thread(
new ThreadStart(DoNetworkThing));
thread.Start();
The documentation for Thread.SetProcessorAffinity states that on XNA, cores 0 and 2 are reserved for the framework; core 1 and cores 3-5 are free for your use. The main thread (the thread containing your main() function) will be on core 1. The code above arbitrarily sets the thread to run on core 3, but you can choose a different core, or add code to programmatically choose a core (which you may want to do if you have more than a few threads).
Finally, note the #ifdef guard - Thread.SetProcessorAffinity is only available on Xbox; it won't even compile on Windows!
OK, so first of all- creating a new thread does have some minimal overhead, but you're only creating the thread once (or a few times)... so unless you're creating hundreds of threads (which you shouldn't be), then you will not need to worry about the overhead.
Let's look at your first example:
Thread thread;
thread = new Thread(new ThreadStart(DoNetworkThing));
// you should set the thread to background, unless you
// want it to live on even after your application closes
thread.IsBackground = true;
thread.Start();
If you were sticking with that model, the DoNetworkThing function would look like this:
void DoNetworkThing()
{
while(someConditionIsTrue)
{
// do the networking stuff here
}
}
I presume that in your next attempt you did something like this:
Thread thread = new Thread(()=>
{
while(true)
{
DoNetworkThing();
}
});
thread.IsBackground = true;
thread.Start();
Both approaches are fine, but the only difference is the content of DoNetworkingThing. In the second approach it will look like this:
void DoNetworkThing()
{
// do the networking thing, but note
// that this time your infinite while
// loop is outside the function
}
Now you said that both of these attempts are really slow, but nothing given in your examples would indicate that there should be any noticeable performance impact. It would be great if you can:
Give us an example that would demonstrate the slow down.
Tell us how many cores you have on the machine that the game is running on.
Finally, if you're mingling with threads then I would STRONGLY suggest that you pickup a good book on multithreading and really familiarize yourself with the concepts behind it, go through the exercises and write a couple of simple programs. It will take you a couple of months, but if you're not familiar with threading then it will help you learn how to avoid a lot of ugly mistakes.
A lot of people recommend Joe Duffy's Concurrent Programming on Windows, but feel free to check some other C# multithreading books too.
It might be worthwhile to check if using a ThreadPool improves performance. Creating many threads may be expensive.
http://msdn.microsoft.com/en-us/library/h4732ks0(v=vs.100).aspx
I'm trying to obtain a good understanding of multi-threading in C# and I'm a bit confused about the applicability of the Thread.Join method. Microsoft says that it "Blocks the calling thread until a thread terminates." Two questions:
Given the following example, which thread is actually blocked while the other is working toward termination?
Doesn't the fact that one thread is blocked while the other is executing toward termination actually defeat the purpose of multi-threads? (So I assume you only want to join in certain situations. What might those be?)
static int Main()
{
Alpha oAlpha = new Alpha();
Thread oThread = new Thread(new ThreadStart(oAlpha.Beta));
oThread.Start();
oThread.Join();
}
I should also note that it is wholly possible that I'm not doing something correct here.
Main is blocked until oThread Completes.
The idea is that you can terminate on thread cleanly and wait for it to clean up after itself, rather than killing the thread sloppily.
It is also useful for starting a batch of three or four independent processes, and then continuing once ALL of them complete.
the thread that is running the Main() method blocks.
Threads often need to synchronize, for instance, if you didn't want your main method to exit until all the work was done. In your example, there's no benefit, but you could insert useful work in between the Start() and Join() calls. This is particularly useful if you spin off multiple threads and then join them all.