CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    May 2005
    Location
    Ellesmera
    Posts
    427

    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.
    *** Con Tu Adios, Te Llevas, Mi Corazon***

    Traveling Encoder...

  2. #2
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    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

  3. #3
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Thread Performance Improvement (A little Advice Please)

    Quote Originally Posted by ideru View Post
    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

  4. #4
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Thread Performance Improvement (A little Advice Please)

    Quote Originally Posted by ideru View Post
    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.

  5. #5
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Thread Performance Improvement (A little Advice Please)

    Quote Originally Posted by OReubens View Post
    Or, if you do, that will be exactly the places where your UI can stutter and become jerky.
    Or you can lose data.

  6. #6
    Join Date
    May 2005
    Location
    Ellesmera
    Posts
    427

    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
    *** Con Tu Adios, Te Llevas, Mi Corazon***

    Traveling Encoder...

  7. #7
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    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

  8. #8
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Thread Performance Improvement (A little Advice Please)

    If you are using c++11, then there is the c++11 multi-threading support. See http://www.cplusplus.com/reference/multithreading/

    Also the books
    C++ Concurrency in Action: Practical Multithreading
    http://www.amazon.co.uk/gp/product/1...rch_detailpage

    and Intels Threading building blocks
    http://www.amazon.co.uk/gp/product/0...rch_detailpage
    https://www.threadingbuildingblocks.org/
    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)

  9. #9
    Join Date
    May 2005
    Location
    Ellesmera
    Posts
    427

    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.
    *** Con Tu Adios, Te Llevas, Mi Corazon***

    Traveling Encoder...

  10. #10
    Join Date
    May 2005
    Location
    Ellesmera
    Posts
    427

    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.
    *** Con Tu Adios, Te Llevas, Mi Corazon***

    Traveling Encoder...

  11. #11
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    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
  •  





Click Here to Expand Forum to Full Width

Featured