About This File
setaffinity is an application for setting affinity masks on Windows processes and executables (generally files with a .exe extension). Affinity masks are only important on systems with 2 or more virtual/physical processors, like an AMD dual core or Intel HyperThreading CPU, as well as more complex setups. An affinity mask controls which of the processors in the system an application is allowed to use. For example, you can restrict an application to a single processor, or allow it to run on all of them.
An affinity mask is simply a number, the value of which determines the processors that may be used by an application with that mask. Processors in the system each have a unique value in the mask. The first processor has value 1, the second value 2, the third value 4, and so on. To create a mask for a particular set of processors, you simply add the values for those processors together and use the result as the mask. On a 2 processors system there are 4 possible masks (remember CPU0 has value 1, CPU1 has value 2):
- 0 (this is always the default when a mask hasn't been set, it allows the application to use all processors)
- 1 (only allows use of CPU0)
- 2 (only allows use of CPU1)
- 3 (allows use of CPU0 and CPU1, equivalent to 0 for 2 processors)
In a 4 processor system, there are many more possible combinations, but here are a few examples:
- 7 (CPU0 = 1, CPU1 = 2, CPU2 = 4, and since 1+2+4 = 7, this means a mask of 7 will let an application use CPU0, CPU1, CPU2, but NOT CPU3)
- 4 (only allows use of CPU2)
- 12 (only allows use of CPU2 and CPU3)
Setting affinity masks can be useful because some applications and games do not run properly on a multiprocessor system. Restricting such applications to a single CPU using an affinity mask will often solve this type of problem. It's possible to update the affinity of running processes using the normal Windows task manager, but this can be annoying. Firstly, you can't update the affinity until the process is actually running, which can mean Alt-Tabbing out of a game, running Task Manager, finding the correct process, updating the affinity, then Alt-Tabbing back in. Secondly, the changes you make are temporary; when the process terminates, the updated affinity mask is not saved, so next time you start it the affinity is back to the default value. setaffinity.exe offers a couple of methods for getting around these problems, which are detailed below.
By default the application starts minimized to the system tray. You can left click the icon to display the window, or use the "Restore" option in the right click menu.
There are 4 main parts to the application window. The first allows you to view and change affinity for running processes, similar to what you can do with the Windows Task Manager. The second allows you to insert an affinity mask into an exe file (while it isn't running), so that every time you start the application from then on, it will use that mask automatically. The third part of the application can optionally monitor the creation of new processes, and set an affinity mask for them automatically. Each of these are described in more detail in the following sections. The fourth part allows you to install and control a small Windows service that can be used to do the process monitoring instead of setaffinity itself. To exit the application, use the "Exit" button or select "Exit" from the tray icons right click menu.
Viewing or setting affinity on running processes
The top left part of the application window consists of a list of processes. The list is NOT updated dynamically, so at first it will just show the processes that were active when setaffinity was launched. You can update the list at any time by clicking the "Refresh list" button. Each entry in the list shows the process name with the process ID in brackets. Clicking on a process entry will cause the second list to update itself. This list contains an entry for each CPU detected in the system, numbered from 0. When a process is selected from the list on the left, the CPU list will highlight the entries for the CPUs that the process is currently able to run on. In the screenshot, the firefox.exe process is only allowed to run on CPU0. Updating the affinity is done by changing the CPU list. To allow the firefox.exe process to use both CPUs, you would simply need to click on the "CPU 1" entry in the list. The changes are applied immediately.
If you select an item in the list and right click it, you can add it to the process monitoring list to the right of the window. See below for more details.
Setting affinity masks in executables
The bottom left part of the application window is concerned with setting affinity masks in executable files. The first step in this procedure is to enter a filename into the "Executable (full path)" field. There are three ways to do that; type it in, click the "..." button and browse for the file you want, or drag and drop the exe into the setaffinity window.
Once the executable filename is entered, you can start to perform various operations on the executable. Note that the exe must NOT be running, or the operations will fail.
- Toggle uniprocessor bit: this button flips a bit in the executable header which when set, restricts the process to a single CPU (but does not allow you to choose which one). The default state is unset, so that the process can use any CPU.
Set affinity mask: this button attempts to set an affinity mask in the executable. To enter the mask value, use the "Mask" textbox. As described above, the mask is just a number. The three buttons to the right of the textbox are there to help enter masks. CPU0 and CPU1 are shortcuts to masks that allow a process to run only on CPU0 or CPU1. The "?" button will examine the current value of the mask and tell you if it's valid or not. If it is valid, it will also list the processors the mask would allow. You should use this button to check if a mask is correct before setting it.
Since setting a mask like this involves modifying the executable, setaffinity.exe will by default create a backup before performing the modification. This backup will be called (name of original exe).bak.
- Reset mask: this button resets the values of the uniprocessor bit and affinity mask in the selected executable to their default states.
- Check exe: this button checks the current values of the uniprocessor bit and affinity mask in the selected executable.
Monitoring process creation
Unfortunately, it isn't always possible to set an affinity mask in an executable. For example, Valve's Steam application appears to redownload or replace modified executables when first started, presumably as an anti-cheating/cracking precaution.
To avoid having to set affinity manually every time a process is started, setaffinity.exe can optionally monitor the creation of new processes by "hooking" the Windows API call CreateProcess, and so set the affinity mask for particular processes without user intervention. By hooking the CreateProcess function, setaffinity can be notified each time a new process is launched (by any application). When it receives a notification, it checks if the new process is present in the list shown on the right side of the window, and if so it will set the associated affinity mask automatically.
To take advantage of this, you first need to add one or more .exe files to the list on the right side of the application window, using the "Add a process" button. By default, newly added applications have the default affinity mask of 0. You can also select a process from the list shown on the left side of the setaffinity window, right click it, and select "Add to monitoring list". In this case, setaffinity will check the current affinity mask for the process and use that as the initial value for the monitoring mask.
Once a .exe file is added to the list, select it, type the mask you want to set into the textbox underneath the list, then click the "Save" button to store it for future use. The "?" button is again used to check that the given mask is valid. You can remove a process from the list by selecting it and clicking the "Remove selected process" button. The application saves the process names and masks in a text file called "hook_list.txt" when closed, and the entries in this file are loaded back in when the application is restarted. The file format is simple, each line consists of the executable path and its affinity mask, separated by a comma:
executable path and filename,affinity mask
The application will look for hook_list.txt in the directory containing the executable. Manual editing of the file is fine, just make sure you do it while the application isn't running, otherwise your changes will be overwritten when it exits.
To actually activate the automatic affinity updating, you must click the "Activate process monitoring" button, and leave setaffinity.exe running in the background. You can turn the monitoring off by clicking the button again, through the right click menu on the tray icon, or by closing setaffinity.exe.
Applications in hook_list.txt that are running when setaffinity is started will have their affinity masks updated without activating the process monitoring. For example, if you have "c:\foo.exe,2" in hook_list.txt, and foo.exe happens to be running when setaffinity.exe is first launched, it will detect this and set the affinity mask for that process to 2.
The application can also now restore the previous process monitoring state on startup, so if you have monitoring active, exit the application (eg to reboot) then start it again, monitoring will be reactivated automatically. This is done by testing for the presence of an empty file called "procmon" in the application directory. If the file is found, monitoring is activated. If you have problems with process monitoring for some reason, you can prevent it from starting automatically by deleting this file before running setaffinity.exe.
Monitoring process creation with setaffinity_service.exe
As an alternative to leaving the setaffinity.exe application running in the system tray, you can install setaffinity_service.exe. This is a Windows Service rather than a normal application (it runs in the background and has no visible windows etc), just like those listed in Control Panel -> Administrative Tools -> Services. To use this service, run setaffinity as normal, then click the "Install" button at the bottom of the window. This installs the service, so that you should now be able to see it listed in the Control Panel with the rest of them. The service will be configured to run automatically each time the system is booted up. To start the service immediately after installing, just click the "Start" button. The "Stop" button stops the service but leaves it installed. The "Remove" button uninstalls it (you must click "Stop" before clicking "Remove").
The service reads the same hook_list.txt file as setaffinity.exe, so you can still use the application to add new processes and update masks as usual. This also allows the application to signal the service when the file is updated, so that the service can reread the file. If you edit the file outside of setaffinity.exe, restart the service to force it to reread the file.
To avoid conflicts, the process monitoring functionality in setaffinity.exe will be disabled while the service is installed (even if it's not running).
The service will create a logfile in the setaffinity directory called setaffinity_log.txt. You can use this to check if it is correctly setting the affinity for the processes you have selected.