Articles   Members Online: 3
-Article/Tip Search
-News Group Search over 21 Million news group articles.
-Delphi/Pascal
-CBuilder/C++
-C#Builder/C#
-JBuilder/Java
-Kylix
Member Area
-Home
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Login/Logout
-Become a Member
-Why sign up!
-Newsletter
-Chat Online!
-Indexes NEW!!
Employment
-Build your resume
-Find a job
-Post a job
-Resume Search
Contacts
-Contacts
-Feedbacks
-Link to us
-Privacy/Disclaimer
Embarcadero
Visit Embarcadero
Embarcadero Community
JEDI
Links
How to use the Affinity Mask in multi-CPU environments Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
27-Jul-03
Category
System
Language
Delphi 3.x
Views
281
User Rating
No Votes
# Votes
0
Replies
0
Publisher:
DSP, Administrator
Reference URL:
DKB
			Author: Kim Sandell 

When writing applications that are designated to tun in multi-CPU environments, it 
is very useful to be able to control which CPU's the application executes on. By 
optimizing the CPU usage one can dramatically increase the performance of the 
application

Answer:

Introduction 

When writing applications that are designated to tun in multi-CPU environments, it 
is very useful to be able to control which CPU's the application executes on. 

By optimizing the CPU usage one can dramatically increase the performance of the 
application. 

Affinity Masks - Background 

When a process is created in windows, an affinity mask is passed to it. This is 
usually the system affinity mask, since the system is launching the process. 

Also by default each thread created by this process is now assigned the current 
affinity mask for the process. This means that the thread is executed in any of the 
available CPU's. 

If the "Process Affinity Mask" is changed, all threads created after that will only 
be allowed to execute in any of the available CPU's, also the whole process is 
limited to the same CPU's. 

Getting the Affinity Mask 

Windows provides us with an API call that help us get the affinity mask. 

The API call is: 

GetProcessAffinityMask(hProcess: Cardinal; var procAFMask, sysAFMask);

The hProcess parameter is the current process handle, and the procAFMask and 
sysAFMask variables are cardinals. 

Before we change the affinity mask, we first need to get the current affinity mask 
for the whole system. This is because we do not want to try to set an affinity mask 
that is not possible. 

When the API call returns it puts the BitMASK for the CPU's in each of the 
parameters. 

The bits are encoded as followes: 

BitMask 	CPU's 
00000001	1st CPU
00000010	2nd CPU
00000100	3rd CPU
00001000	4th CPU
00010000	5th CPU
00100000	6th CPU 
01000000	7th CPU
10000000	8th CPU

By combining these BIT values one can determine the CPU count/mask. The BitMask is 
32 bits in size, so theoretically the BitMask supports up to 32 CPU's. 

Example:  BitMask=00000011 would mean 2 CPU's, number 1 and 2. 

Changing the Affinity Mask of a Process 

Windows provides us with an API call that help us set the affinity mask. 

The API call is: 

SetProcessAffinityMask(hprocess: Cardinal; ProcessAffinityMask: Cardinal); 

The hProcess parameter is the current process handle, and the ProcessAffinityMask 
variable is a cardinal. 

To obtain the current process handle we need another API call named 
"GetCurrentProcess()".  This API call returns the handle of the current process. 

The ProcessAffinityMask variable contains the BitMASK of the CPU's we want this 
process to execute on. (see the BitMask table above). 

Example: 

1   var
2     ProcAFMask,
3       SysAFMask: Cardinal;
4   begin
5     { Get the current values }
6     GetProcessAffinityMask(GetCurrentProcess, ProcAFMask, SysAFMask);
7     { Manipulate }
8     SysAFMAsk := $00000001; // Set this process to run on CPU 1 only
9     { Set the Process Affinity Mask }
10    SetProcessAffinityMask(GetCurrentProcess, SysAFMAsk);
11  end;


A realworld example 

Now that I have shown how to get and set the affinity masks for processes, I'd like 
to show a real-world example of how to utilize this. 

I had a situation where our customer had a 4 CPU server, and used it for some heavy 
processing about 80% of the time. 

The customer wanted us to create an application for them, but they didn't want to 
invest in the hardware, since they already had a good server running. They where 
unsure of the total load on the server so we investigated, and found that the 
server only used the 2 first CPU's when under heavy load. This meant that there 
were 2 CPU's available for us ! 

So we implemented the Affinity Mask API calls, and concluded that our application 
was executing nicely on CPU's number 3 and 4 only, leaving the 2 other CPU's free 
for the other application on the server. 

Our application used alot of Threads, but since the master affinity for the whole 
process was changed, the threads followed the set parameters without problems. 

What about the affinity masks for the Threads? 

If you want to read more about the affinity masks for Threads there is an excellent 
article: 

Extending TThread for multiple processor environments

			
Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10

 

Advertisement
Share this page
Advertisement
Download from Google

Copyright © Mendozi Enterprises LLC