05-05-2006 12:00 PM
05-05-2006 12:53 PM
05-05-2006 01:00 PM
05-08-2006 09:18 PM
05-09-2006 08:18 AM
05-09-2006 10:50 AM - edited 05-09-2006 10:50 AM
Message Edited by RadioAct on 05-09-2006 11:16 AM
05-09-2006 11:33 AM
I guess about 15% of my CVI apps use a multi-threading approach. Usually I reserve it for when I need tight control and response from a custom piece of hardware - normally combined with raised thread priorities as well. For 'normal' OS/GUI type apps I just stick to the one thread. Careful choice of timer callbacks and calls to ProcesssystemEvents() can offer a very high performance level (CPU @ 100%) at the same time as maintaining GUI Control responsiveness.
Don't make the mistake of thinking that more threads == more processing power. One CPU gives you X amount of processing power, no matter how many slices you cut the pie into. It can seem that you are making things better, certainly if you also raise priorities as well, but it is not a magic bullet solution to performance issues.
JR
05-09-2006 12:13 PM
05-09-2006 05:04 PM
RadioAct -
You are correct, as a general rule most threads actually spend most of the time waiting for I/O. Creating multiple threads simply allows better utilization of compute bandwidth. You can use the Windows task manager to prove to yourself that this is the case - there are typically hundreds of threads active and CPU utilization is below 10% for a typical mix of desktop applications. And you'll be able to see that almost every active process is multi-threaded. Heck, even the idle process is multi-threaded on a hyperthreaded or multi-cpu system!
If you ever see a Win32 based system compute bound for more than a moment or two it's very likely a case of a misdesigned process.
Bear in mind that (save for the "Task Manager" the term task isn't used in Win32 - it's processes and threads. All processes have at least one thread. In computing science a "task" is generally considered to be a process with a single thread.
All scheduling in Windows is on a thread priority basis. The scheduler uses a priority based scheme to decide which thread to schedule and allocates it a quantum of time (typically a few tens of milliseconds) to execute. All threads from all processes are kept in a series of queues at the various thread priority levels. Bear in mind that the thread scheduler algorithm varies somewhat from OS to OS (NT's is a bit different from Win2K's, etc.)
Windows uses a "priority class" concept that groups the thread priorities for a given process into one of several groups - realtime, high priority, etc. The names and number of priority groups varies by OS too BTW 😉 You can change the priority class programatically (which changes the priority of all of the threads in the process) as well as the priority of an individual thread. See the Win32 SDK for details.
You should be able to set thread priorites at process / thread startup so as to get desired behavior - the whole point of the OS's multi-level process thread scheduling scheme is just that - so you don't have to be dickering with them all of the time. Most user processes work best at the "normal" priority class - that 's the design intent. The scheduler will boost thread priority at certain times based on heuristics Microsoft has built in. It also varies the number of execution time "quanta" as part of the scheme - the amount of time a thread is allowed to execute before pre-emption. It can be a challenge to get a complete and accurate description of the scheduler's behavior for a particular Win32 OS. It varies even by the OS version for some of them.
You might find that changing the thread priorities has less of an effect than you'd imagine.
Windows also allows you to establish a more general behavior of the thread scheduler by characterizing the systems operation as emphasizing "normal" user interface processes or background (service) processes. This tailoring is usually buried somewhere in the control panel.
In VC++/MFC there's the concept of user interface threads and worker threads. User interface threads respond to windows messages (generally equivalent to user interface events in CVI) while worker threads do not.
As a design goal you likely want the user interface to stay responsive (an "Abort" button is classic need).
The Win32 thread schedulers don't have the hard determinism of a real-time OS like VxWorks or QNX. Well, Windows CE does have strict priority based scheduling but none of the others do. And I'd stay away from the realtime priority class.
The Win32 SDK documents the calls needed to change thread priorities.
I could go on forever but don't have the time 😉 Read Beveridge and Weiner. Read the NI whitepapers on multi-threading. Read the Win32 SDK docs on processes and threads.
Hayes