According to Microsoft, understanding how Windows works is no easy task. If you're a regular home user, they imply, there's no need to worry your pretty little head about such technicalities. Get back to playing games and browsing the web: leave the clever stuff to us.
Of course, this isn't entirely true. Sure, most people won't gain anything from studying the data structures that surround a Windows process, for example. However, learning just a few fundamentals can help you to improve your PC's performance, troubleshoot problems and diagnose – or prevent – system crashes. And you don't need a degree in computer science to understand these ideas, either.
Press [CTRL]+[Shift]+[ESC] to launch Task Manager, click the Processes tab and you'll see a lengthy list of programs running on your system. Click 'Show processes from all users' (on Vista) and you'll add even more, a total of over 60 on our test PC. That's a busy setup, but the reality for your processor could be even worse.
The fact is that a Windows process doesn't 'run' anything at all. It's just a collection of data relating to a program. Every process contains at least one thread, though, and it's this that executes program code. Click 'View | Select Columns', find and check the Threads box, click 'OK' and you'll see that virtually all your processes have more than one thread. And many have considerably more: numbers of 10, 20 or 30 are by no means uncommon. Our test system had more than 600 threads listed, without opening a single application.
This doesn't mean all 600 threads want to run simultaneously, though, and Task Manager can reveal this, too. Click 'View | Select Columns', check 'CPU Time' and click 'OK': you'll see most processes have very little or no recorded CPU use at all. These are like Windows Services, set up and ready to run, but not actually consuming any CPU time until you need them for something.
Still, even if some threads are dormant, there will often be more running than your CPU can handle at once. So how does the system decide which thread gets the most attention?
Windows assigns every thread a 'quantum', which is a length of time that it's allowed to run before another thread may get a turn on your CPU. Consumer editions of Windows use a short quantum, perhaps 20 milliseconds, which means no task should be able to grab the processor for very long.
The system also triples the quantum of the foreground application, so its threads get 300 per cent more CPU time than the competition. That's a good way to ensure that whatever program you're working on stays snappy and responsive, but there's a price to pay.
Every time your CPU swaps threads it must also perform a context switch, where it saves the state of one thread and then recalls the state of the next. And this takes a short – but still measurable – amount of time. A short quantum makes for a responsive interface, then, but also increases the overhead for your CPU. It spends a lot of time just managing the system rather than getting on with running your threads.
As a result of this issue Microsoft Server products use a long quantum, six times longer than consumer Windows and so make far more efficient use of the CPU. Sounds useful? It's easy to try this for yourself. Open the System applet in Control Panel, click 'Advanced' (then 'Performance Settings | Advanced in Vista') and set 'Adjust for best performance of' to 'Background services'. Windows will now set your PC to use a long quantum with no foreground boost. This means reduced CPU overheads and better overall performance, especially on systems that run a lot of programs.
However, the new setting might mean that some programs become more jerky or games begin to stutter. If it doesn't work for you, then there's a Registry setting you can tweak: 'HKEY_LOCAL_MACHINE\ SYSTEM\CurrentControlSet\ Control\PriorityControl\Win32 PrioritySeparation'. Setting it to '16 (Hex)' delivers a long quantum with a high foreground boost to combat jerkiness. See the table on the next page for more options.
Quantums are interesting, but the real key to thread scheduling lies in its priority. When a program is launched, its process is assigned one of six priorities: Realtime, High, Above Normal, Normal, Below Normal or Idle. Each thread for the process then inherits this priority, which is used to determine which one runs next. A High priority thread will usually be preferred to one with Normal priority, for instance.
Won't this mean some threads run all the time? Not quite. Most threads only have a limited task to perform – like 'spell check this document' – and at some point they'll be finished. And if a thread accesses hardware, perhaps opening a file, then it may enter a wait state until the device returns some information. Windows notices this and schedules another thread to run in the meantime.
In addition, a Windows component called the Balance Set Manager runs every second, looking for threads that haven't had any recent CPU attention and giving them a temporary priority and quantum boost. You'll probably have seen this at work yourself, when a process seems to grab 100 per cent of your CPU time, yet other programs still respond – though very, very slowly. That's the Balance Set Manager kicking in.
It can be useful to tweak process priorities for yourself. If a rogue process starts grabbing 100 per cent of CPU time, press [CTRL]+[Shift] +[ESC] to launch Task Manager. Select the Processes tab and click the CPU column header (click 'View | Select Columns' and check 'CPU' if you don't see it) to sort by CPU use, so you can easily spot the resource hog. Then right-click that process and choose 'Set Priority | Below Normal'. This should allow other threads to be scheduled again, letting you regain control of your PC.
You can also use 'start.exe' to launch processes with the priority of your choice. To do so, right-click your program shortcut and modify the Target to something like: cmd.exe /c START /low c:\path\app.exe.
Use '/low' for a process that you don't want to grab CPU time, or '/ high' when speed is vital. Boosting a thread's priority to High can give you a five or 10 per cent performance gain, but use this technique sparingly: remember, you're borrowing these CPU cycles from other processes and these will be slowing down. Many Windows processes also work at higher priorities and if they're blocked because you're running a game, say, your system could crash. Our advice: run only one priority-boosted app at a time and experiment with the new setting for a while before you assume that it's stable.
Running a process at a low priority can be taken too far in cases where processor attention is limited so much that the program gets almost no work done.
However, there is another way to free up your CPU's time. Virtually all modern PCs now come with either a dual- or quadcore CPU. These provide two or four physical processors, each of which can be running a thread at any given time. There's no special rule for sharing out these extra CPUs, though: Windows looks at quantums and priorities just as normal, and there's nothing to stop a multithreaded application tying up your processors all on its own.
You can do something about this by defining the CPU affinity for this process, as in the CPUs it will be allowed to run on. In Task Manager, click the Process tab, right-click the process, select 'Set Affinity' and clear all but one of the CPU boxes. On a dual-core processor, this means the process will now only run on one of your cores. Even if you leave it at a normal priority, the program still shouldn't grab all your CPU time, leaving you able to do other things.
It's also possible to launch a program with a given affinity setting, again thanks to the very useful 'start. exe' command, although you do have to calculate an affinity mask first. Essentially, the first core has a value of 1, the second 2, the third (if you've a quad-core system), 4, and the fourth, 8.
Decide which cores you'd like the process to run on, then add those values together to produce the affinity mask: just core 1 and it would be 1, cores 1 and 3 would be 5, and so on. Convert values over 9 to hex, then specify them in your shortcut like this, replacing 'm' with your affinity mask: cmd.exe /c START AFFINITY m c:\path\app.exe.
This is a useful technique to apply occasionally, if there's a specific program that you don't want to grab all your CPU time, but be careful. Generally, the less leeway you give to Windows own thread scheduler, the more inefficiently your PC will run. Just like priority boosting, it's best to use CPU affinity tweaks sparingly.
Controlling how your processes access the CPU is an excellent first step in optimising a PC, but there's plenty more work to do. And learning something about the limitations of your system resources can be particularly useful, at least for 32-bit Windows users. (If you're using 64-bit Windows this next section won't apply to you, sorry.) 32-bit Windows allocates 2GB of virtual address space to each process you run.
The Windows kernel also only gets 2GB to store everything – kernel code, drivers, DLLs and all the components it needs to keep your system running – so all resources are strictly rationed. Virtual memory allocations by kernel components like DLLs are taken from something called the 'paged pool' and on a 2GB Windows XP PC, that defaults to a maximum of 360MB in size.
Drivers often require memory that is guaranteed never to be paged to disk and that's taken from the 'nonpaged pool' (which defaults to a maximum 262MB on a 2GB XP PC).
Windows XP doesn't let these pools grow to meet demand, so if a buggy driver grabs all the pool memory, odd things begin to happen: error messages, network failures, hangs and more. Windows XP users can make the situation even worse if their PCs have 4GB of RAM and they use the '/3GB' switch to try and give applications access to more memory (see http://support. microsoft.com/ kb/833721 for more information). This squeezes Windows own address space down to a mere 1GB, making resources drop still further.
The maximum non-paged pool falls from 285 to 154MB and system page table entries (a resource used to map virtual to physical memory, see www.tinyurl.com/ 6j5wmg) plummets from 106,000 to around 15,000. If you've used the '/3GB' switch and your PC is now unstable, that may be why. Remove it and see what happens.
32-bit Windows Vista improves on this situation in many ways. It can now dynamically allocate new memory if either pool needs it, so your system will keep running. Still, if you've a resource leak – a process that keeps grabbing objects and doesn't release them – then even Vista will run into problems eventually. That's why everyone can benefit from monitoring their PC's resource use.
The simplest way to check your current Windows resources is through Task Manager. Press [CTRL]+[Shift]+[ESC] to launch it, select the Processes tab, click 'View | Columns' and ensure the 'Memory – Paged Pool', 'Memory – Non-paged Pool', 'Handles', 'USER Objects' and 'GDI Objects' are checked. Reboot your PC and make a note of the highest value in each case, as well as the paged and non-paged totals displayed on the Performance tab.
An hour or two later, take a look at Task Manager again. Anything using several thousands of handles, GDI or USER objects should be looked at closely, and Windows XP users should be concerned if non-paged pool use is over 200MB or paged pool allocations have passed 250MB. This may not mean buggy software – your application may simply be doing a lot of work – but this can help point you in the right direction. Google the process name to find out more.
The Windows Performance Monitor can also help display this data, along with some other figures that Task Manager doesn't provide. Launch 'perfmon.exe', click the plus sign to graph a new value, then open the Memory counters and choose 'Free System Page Table Entries'. If this is very low, perhaps a 1,000 or less, then you may also have a resource leak somewhere.
So where is it? If you're regularly getting complete PC crashes – the 'blue screen of death' that kills Windows and forcibly reboots your system – then there's one suite that can probably help you find out: the Windows Debugging Tools. Sure, they're aimed at developers, and they're complicated and packed with jargon, but they can also take a crash dump file and let you know whether resource problems were the cause. If they're not, then you can get some very helpful clues about the real culprit. And, despite their technical reputation, using the Debugging Tools at this level is very, very easy.
Start by downloading and installing the appropriate debugging package for your system (www.microsoft.com/whdc/devtools/debugging/ debugstart.mspx).
You'll be using the debugger to diagnose memory crash files, so first you need to make sure that Windows is set up to create them. Right-click My Computer, select 'Properties | Advanced' and check the Startup and Recovery settings to ensure that 'Write debugging information' is set to 'Kernel memory dump' (unless you have good reason to do otherwise).
Click 'Start | All Programs | Debugging Tools for Windows' and launch WinDBG. (In Vista, make sure you right-click the WinDBG shortcut and select 'Run as Administrator'.) Click 'File | Open Crash Dump' and browse to your last crash dump file, perhaps '\Windows\ Memory.dmp' or a file in the '\Windows\ Minidmp' folder.
The debugger needs to download information from the web to help figure out the contents of your file, so be patient. You'll know when it's finished because a '0: kd>' prompt will appear in the bottom left-hand corner.
You should then see some basic information about the error type; 'Access violation – code c0000005' or whatever, and perhaps a DLL name as well. It's all data that might be useful if you want to search for online references to the error later. However, there's better to come. Once the debugger is ready, click in the command window to the right of the 'kd>' prompt and type the command: '!vm'.
After pressing [Enter], you'll be able to see how your virtual memory was being used at the time of the crash, including details for resources like paged pool, non-paged pool and system PTEs. The maximum values are displayed too, so it's easy to spot whether or not there was a resource problem at the time of the crash.
What if the resources all look fine? No problem – just enter this command instead: '!analyze -v'.
The debugger will now look at the record of what was going on at the time of the crash and tell you which file it thinks is most likely to be responsible. This may take a while, but it pays to be patient: in our tests, the debugger regularly managed to produce useful information. In the most recent test that we performed, it explained that our Windows crashes were probably caused by 'pctfw2.sys'. A quick visit to Google told us that the file was connected to the PC Tools Firewall and updating the program successfully solved the problem.
Of course, the debugger isn't right all of the time. Sometimes the '!analyze' command displays no useful information at all – and on other occasions, it'll blame the wrong file entirely. Results pointing to 'ntoskrnl', 'win32k', 'hal', 'ntfs' and other core components are usually false alarms and you shouldn't take any verdict as guaranteed. And you absolutely must not explore other debug commands or options while you're doing anything important in other applications. You could easily crash your own PC.
Still, cautious debugging frequently produces invaluable troubleshooting results which you simply can't discover any other way and this means that it's definitely worth a try. So don't be intimidated by the apparent complexity of these developer-oriented tools and techniques. Learning just a few low-level Windows details really can deliver positive results for everyone.