1

Sorry if this has been asked, I did my best to search for a dup before asking...

I am implementing a video processing application that is supposed to run real time. The processing it does can be easily divided into 4 stages, each one operating on the intermediate values generated from the previous stage. The processing has become heavier than what can be processed in 1/30th of a second, but if I can split this application in 4 threads and turn it into a pipeline, each stage takes less than that and the whole thing would run realtime (with a 4 frame lag, which is completely acceptable).

I'm fairly new to multithreading programming, and the problem I'm having is, I can't find a mechanism to start/stop each thread at the beginning of each frame, so they all march together, delivering one finished frame every "cycle" at the end. All the frameworks/libraries I found seem to worry about load balancing using queues and worker threads, but this is not what I need here. Four threads will do, assuming I can keep them synced.

Can anybody point me to a starting point, using C++?

Thanks.

  • Are you using a threading library (ie boost)? Or vanilla POSIX? – wbennett Jul 16 '14 at 20:54
  • May be a [`std::condition_variable`](http://en.cppreference.com/w/cpp/thread/condition_variable) could help for your case. It's possible to build a semaphore like synchronization mechanism based on it (see [this question](http://stackoverflow.com/questions/3513045/conditional-variable-vs-semaphore) also). – πάντα ῥεῖ Jul 16 '14 at 20:56
  • @wbennett, I'm not using anything yet, completely opened to suggestiongs. The application all runs in a single thread right now (except for the GUI). – user3846684 Jul 16 '14 at 20:59
  • @πάνταῥεῖ, looked at the link... It seems I could make it work using that, but it looks like a horrible hack... Isn't there a mechanism like a clock, the same way a processor's pipeline works? At each cycle, all threads take the input from the same place,and write their output to the same place? (Not worried about racing conditions or data overwriting, it's completely different data between stages). – user3846684 Jul 16 '14 at 21:04
  • You might want to re-think the problem. If you have a stage dependent on the next, you will only be as fast as your slowest stage (see Amdahl's law). Maybe look at dividing up work horizontally instead of vertically to speedup each stage. Especially if you have soft real-time requirements. – wbennett Jul 16 '14 at 21:12
  • @wbennett, I know, each stage cannot take longer than 1/30th of a second, and that's all I care about.. if one stage finishes really quickly and sits there idle, that's fine, as there would be nothing else for it to do anyway... I don't want to finish processing as fast as possible, I want to keep it steady at the same rate video frames are coming in... the problem is really making sure they all start their processing at the same time at each frame, besides the stages are all pretty load balaced as it is, so that's not a concern... – user3846684 Jul 16 '14 at 21:20
  • I believe I have found what I'm looking for, it's called the "Producer-consumer problem". Any suggestions of a nice C++ multithreaded implementation of it is very welcome, but I believe I have enough to carry on for now. Thanks all for the help! – user3846684 Jul 16 '14 at 21:26

1 Answers1

0

Assuming a 4 frame lag is acceptable, you could use a pool of list nodes, each with a pointer to a frame buffer and a pointer to the intermediate values (a NULL pointer could be used to indicate end of a stream). Each thread would have it's own list as part of multithread messaging system. The first thread would get a frame node from a free pool, do it's processing and send the node to the next threads list, and so on, with the last thread returning nodes back to the free pool.

Here is a link to an example file copy program that spawns a thread to do the writes. It uses Windows threading, mutexes, and semaphores in the messaging functions, but the messaging functions are simple and could be changed internally to use generic equivalents without changing their interface. The main() function could be changed to use generic threading and setup of the mutexes and semaphores or something equivalent.

mtcopy.zip

rcgldr
  • 27,407
  • 3
  • 36
  • 61
  • Thanks for the suggestion and the source code, very helpful. I was,however, trying to avoid the whole pool/queue messaging between threads, because I don't think it fits the nature of my algorithm. Threads will never "outrun" one another, they all do their job in the interval between frames coming in from the video source. I just need a mechanism to tell all threads at the same time when to start doing their work on the new frame (each on it's own part of the processing pipeline). If that makes sense... – user3846684 Jul 16 '14 at 22:53
  • The trade off is a somewhat awkward start up sequence, since it's a staged process (based on your post that each thread uses the intermediate values produced from another thread). The second thread doesn't have anything to do until the first thread has completed the first frame. The fourth thread doesn't have anything to do until the third thread has completed the first frame. Using a messaging system simplifies the startup, and if you look at the example code, the actual messaging functions are small. – rcgldr Jul 16 '14 at 23:41
  • An alternative to messaging would be the usage of event or condition variable to trigger each thread. – rcgldr Jul 17 '14 at 02:26