I’ve been meaning to look into this for a while, but not had time.
How can we program applications some that some functions run on one processor, and other functions on another?
I understand that ofxThread is to stop errors with processes accessing the same object at the same time, although I don’t know how to make things run on different processors.
Any advice on this topic would be more than welcome, and of interest to many other people I’m sure.
In fact ofxThread allows to create different threads, so it can be used to make an application run on both cores at the same time.
You just have to divide your application in two or more parts (classes) and run that parts as threads (take a look at threadedObject in threadExample), the operating system will do the rest. Well, you have to take care not accesing a resource for writing from two or more threads at the same time.
Also you can use some libraries like intel IPP that it’s already prepared to use both cores.
so you just can thread you application as optimal as possible.
which is really really really hard. there is a lot of information about it out there, but just a few good people who are able to master it.
my recommendation: try to have simple dedicated worker threads (network, framegrabber, serial I/O, I/O, AI, physics) which don’t have to wait/synch so often and never return.
Eight month ago i wrote some multitouch analysis code that ran in two threads. I basically placed the cv stuff in a separate worker thread. When I ran the app it was nicely divided over the two cores. It was pretty straight forward. Here are some tips though:
Make sure all your opengl code is in the main thread. Some graphics drivers will let you get away with putting some of it in threads but your program might then run-time break when you move to a different machine. There is hidden ogl code like the texture in the of video grabber class. Make sure you deactivate it in the thread.
I had problems accessing the video capture settings when I ran the video grabber from a thread. For such quirks it helps if your thread class can both run in a thread or asynchronously.
Handing over info from the thread to the main process can be done by sharing a common object. Make sure only one writes/changes it at the same time. Mutex locks can be used to prevent this. Sometimes your reading thread might catch the thread writing to it in which case the object is in an undefined state. This is usually fine for images. If you are unsure use locks.
Is there a particular website/article you can recommend to learn more about multithreading especially on osX. I would like to learn more about concepts before trying to do something. I think multithreading might be easier to comprehend on a multi-core system but I imagine it could get a little confusing on a single cpu computer.
Well, Threading Building Blocks doesn’t work the same way as threads, so it’s far easier to use.
You create a small objects that can take a chunk of your task to process and let TBB handle how to split it up across CPUs.
Have a read through the PDF that comes with it and look at some of the sample code, it’s pretty simple.
Threads on the other hand, while you can definitely get the concept of them after experimenting a little bit (mutexes etc) there are a lot of different problems you can run into, things not being thread safe, making sure you clean up properly, etc etc.
@ding:
For osx (and unix) multithreading this is a brilliant resource: https://computing.llnl.gov/tutorials/pthreads/
P.S. A single cpu computer can still have multiple cores and run multiple threads simultaneously…
@chris:
I don’t know if its linked to your problem, but did you disable the texture of the videograbber? I had the video grabber running in a separate thread (actually i had six video grabbers running in 6 threads) and if I didn’t disable the texture I was getting a crash because with every frame captured OF was trying to create an opengl texture - and opengl can only run in the main thread. So try disabling the texture, or capture first in the main thread and analyze in a separate thread (I went for the first option).
I recently wrote an app that was using 8 threads (running on 8-core mac pro) and one thing I found, was to use the lock() and unlock() sparingly, i.e. try not to put it on inner functions, but more on outer functions as much as possible so you aren’t creating hundreds of locks per frame etc. Theres a thread (pardon the pun) here http://forum.openframeworks.cc/t/advice-with-multithreading…/813/0
where you can track my progress you can ignore pretty much all of my posts except the last one - it may be useful…
Hi chris, in that case I’m out of ideas i’m afraid!
only hack solution I can think of is quite obvious and is to capture the video in the main thread, then analyse in seperate thread - but thats far from ideal. What kind of camera are you trying to capture from (usb, firewire, capture card etc)? could that be part of the problem?
I’m on OSX and your project works fine for me. If I keep the sleep at 30ms as you have (30ms => 33fps) my isFrameNew is something like 000000001101010101010010101010100 which implies it takes a while to init, and then is capturing at around 15fps.
Sure enough if I set the sleep to 1000/15 = 66ms I get ‘true’ every frame.
(in sleep you tell it how many milliseconds to wait before running again, so you should set it to 1000/desiredFPS)
So if you are not getting any isFrameNew its either a bug on your OS/setup, or something to do with your device settings I think.
Usually you do need to lock and unlock each cycle because unless you get into more complex thread communications your thread isn’t going to know that another thread wants access to the vars, and you can end up in pretty sticky situations!
Are you on windows? the thread version is different from osx/linux to that on windows, so perhaps there’s a problem with the windows version.
Can you try changing line 24 in threadedObject.h:
startThread(true, false);
to:
startThread(true, true);
and posting the output?
About locking/unlocking, you have to call lock whenever you’re going to access some shared variable, so two threads cannot access the same variable at the same time. For example in your code you should use lock/unlock also in the draw method so the frame do not change while you’re drawing it.