-
April 15th, 2015, 01:24 AM
#1
Thread Performance Improvement (A little Advice Please)
I'm working on how to improve a multi-threading application, hopefully I can, so I need a litle bit of advice from all the guru here.
The program has 2 Main worker Threads:
Thread A: Transceiver thread. It gets data from the buffer of a specific device.
Thread B: Once the Thread A has enough data receive, it analysis it and display it
There are also two display window ( Forms )
Form1 : Setting window. User can set/change any settings even when the thread have already been started
Form2 : Display window, and display settings
Other than that, there is also a file operation involve.
File Output1: Data receive from Thread A
File Output2: Data analyze from Thread B
Right now, I need to make Thread A work smoothly that even if there are any other request like
file ouput, UI operations it should work smoothly and continuosly by getting the data from the devices' buffer.
Thread A should be able to
-> get data from buffer
-> signal thread B to analyze data when data size is satisfied
* Currently , SwitchToThread is used to do this now
-> output data to file when needed.
* Right now, all of this is done in a single while loop.
Any better technique to make these thread perform better?
Sorry for the vague question.
-
April 15th, 2015, 03:25 AM
#2
Re: Thread Performance Improvement (A little Advice Please)
Which compiler (version) are you using? Is this C or C++?
How do you create the threads?
If you want to give thread A priority over the other threads, then you should give it a higher priority. Then you should probably do the file output in a seperate thread.
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
-
April 15th, 2015, 03:51 AM
#3
Re: Thread Performance Improvement (A little Advice Please)
Originally Posted by ideru
I'm working on how to improve a multi-threading application, hopefully I can, so I need a litle bit of advice from all the guru here.
The program has 2 Main worker Threads:
Thread A: Transceiver thread. It gets data from the buffer of a specific device.
Thread B: Once the Thread A has enough data receive, it analysis it and display it
There are also two display window ( Forms )
Form1 : Setting window. User can set/change any settings even when the thread have already been started
Form2 : Display window, and display settings
...
It is not clear to which thread(s) belong these windows.
Note that preferable way for multithreaded applications is:
1. Create all GUI objects (windows, menus, ...) in the main thread.
2. Put all the lengthy operations in the worker thread(s).
3. Put the most of time consumer send/receive operations in the worker thread.
4. Avoid any synchronization as much as possible. Do it only if it is really needed. See The Best Synchronization Is No Synchronization: Alternatives to semaphores, mutexes, and CRITICAL_SECTIONs
...
See also this essay (it is MFC, but the main principle is the same for other languages/frameworks): Using Worker Threads
Victor Nijegorodov
-
April 15th, 2015, 08:14 AM
#4
Re: Thread Performance Improvement (A little Advice Please)
Originally Posted by ideru
Right now, I need to make Thread A work smoothly that even if there are any other request like
file ouput, UI operations it should work smoothly and continuosly by getting the data from the devices' buffer.
THAT is your problem.
don't do other requests, file output and requesting data from the devices' buffer on the same thread that takes care of UI.
Or, if you do, that will be exactly the places where your UI can stutter and become jerky.
-
April 15th, 2015, 09:10 PM
#5
Re: Thread Performance Improvement (A little Advice Please)
Originally Posted by OReubens
Or, if you do, that will be exactly the places where your UI can stutter and become jerky.
Or you can lose data.
-
April 16th, 2015, 02:34 AM
#6
Re: Thread Performance Improvement (A little Advice Please)
Thank you very much for all your wise and intelligent suggestion/explanations
D_Drmmr : I'm currently using Visual C++ 2008 Express Edition
VictorN: Thanks for that steps and article. I run the code using Debug Mode and it produces error case the Worker Thread is illegally or directly accessing the UI Thread. The weird part if the application is run without Debug Mode, it works . I'm slowly working on removing this culprit.
OReubens: Very true. This code needs an overhauling and redesingning.
Arjay : Exactly. That's were the overflow comes in, data is lost because it can't be process anymore.
Again, thank you very much for the response
-
April 16th, 2015, 08:44 AM
#7
Re: Thread Performance Improvement (A little Advice Please)
One way to solve this problem is with the UI thread, a worker thread and a threadsafe std::queue. The thread safe queue will get locked while pushing or popping items (and unlocked immediately afterward).
With this approach, the worker thread reads the data. When the data is of sufficient size, it pushes the data onto the queue and signals the UI thread to take the data off the queue, processes it and then displays it.
As I mentioned the queue is locked the minimum amount of time (only while pushing or popping from the queue). Since the queue lock time is so short, rarely is there ever a problem where the worker thread is waiting to acquire the lock and loses data while waiting. Of course, you'll need to test for this scenario (but it will be dramatically faster than your current one thread approach).
One thing that needs to be stressed is to keep the queue lock time to an absolute minimum.
So DO NOT DO THIS:
Code:
Worker thread - (in data arrive callback)
Lock Queue
Retrieve data
Check if data is correct size
Push data onto queue
Signal UI Thread
Unlock Queue
UI Thread (after getting signaled that queue data is present)
Lock Queue
Pop Data
Process Data
Display Data
Unlock Queue
Instead DO THIS
Code:
Worker thread - (in data arrive callback)
Retrieve data
Check if data is correct size
Lock Queue
Push data onto queue
Unlock Queue
Signal UI Thread
UI Thread (after getting signaled that queue data is present)
Lock Queue
Pop Data
Unlock Queue
Process Data
Display Data
-
April 16th, 2015, 01:16 PM
#8
Re: Thread Performance Improvement (A little Advice Please)
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
May 14th, 2015, 02:11 AM
#9
Re: Thread Performance Improvement (A little Advice Please)
Sorry for the late response. I was working on something else but now I'm back on this again.
2kaud : I'm using C++ 2008 Express Edition
So right now we ( I ) will be reconstructing this code.
I will be using Timer Interrupt , simulating a micon.
Already getting the data for that.
Next step will be to smoothly save this data ( from buffer ) to a file.
-
May 19th, 2015, 10:12 PM
#10
Re: Thread Performance Improvement (A little Advice Please)
So I'm trying to apply some of the advice here and this is what I came up, still having problems so please understand still learning as I go through with this.
I created thread to specifically retrieve data from my device buffer
Code:
Thread^ gTReceive = gcnew Thread(gcnew ThreadStart(this, &Form1::DataReceiverCallback));
gTReceive->IsBackground = true;
gTReceive->Start();
Thread^ gTDraw = gcnew Thread(gcnew ThreadStart(this, &Form1::ThreadDrawProc));
gTDraw->IsBackground = true;
gTDraw->Start();
In DataReceiverCallback,
-> Get Data and Store in LocalBuffer Variable
-> When a specific size is retrieve, execute the Backgroundworker for Saving it to file
-> When computation size is retrieve , execute the Backgroundworker for Computation
BackgroundWorker::Computation
OnComplete-> Set the draw_flag to Signal ThreadDrawProc to draw
ThreadDrawProc draws/update UI .
Unfortunately, my UI is not update so I'm not sure how I'm going to Signal my UI thread to update properly.
-
May 20th, 2015, 01:27 AM
#11
Re: Thread Performance Improvement (A little Advice Please)
Can you set breakpoints and step through the code to find out what isn't working. Alternatively can you log trace statements to find out the order of things and/or if things are getting called?
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|