Visit our Sponsor   Visit our Sponsor
delphi3000.com - the free delphi knowledge platform
delphi3000.com - the free delphi knowledge platform
Have a look at your member-status

connecting people's knowledge


  - Recent ArticlesRSS feed for Recent Articles on delphi3000.com
  - List of All Articles
  - Top Viewed Articles
  - Articles (+Attachem.)
  - Articles Of Interest
  - Categories
  - Top Uploader
  - Search
  - Index

  - My Home
  - Submit an Article
  - My Articles
  - My Personal Data
  - My Bookmarks
  - Activities
  - Login/Logout

  - Sign Up
  - Why Sign Up
  - Newsletter

  - Press
  - Advertise

  - Contact
  - Feedback





Community
Borland
ClubeDelphi
Dr. Bob
UK-BUG
Delphi Meetings
Planeta Delphi







Startblatt.de






Share this article with friendsShare this article with friends
Rate this articleRate this article - to keep the quality of delphi3000.com !
Comment this article or read through previous comments (0)


Using the Affinity Mask in multi-CPU environmentsGo to Kim Sandell's websiteFormat this article printer-friendly!Bookmark function is only available for registered users!
Using Affinity Mask's to control which CPU's the Application executes on
Product:
Delphi 3.x (or higher)
Category:
System
Skill Level:
Scoring:
Last Update:
08/04/2004
Search Keys:
delphi delphi3000 article borland vcl code-snippet affinitymask multi-cpu process thread server
Times Scored:
6
Visits:
4109
Uploader: Kim Sandell
Company: Celarius Oy
Reference: N/A
 
Question/Problem/Abstract:
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:

Var
   ProcAFMask,
   SysAFMask  : Cardinal;
Begin
   { Get the current values }
   GetProcessAffinityMask( GetCurrentProcess, ProcAFMask, SysAFMask);
   { Manipulate }
   SysAFMAsk := $00000001; // Set this process to run on CPU 1 only
   { Set the Process Affinity Mask }
   SetProcessAffinityMask( GetCurrentProcess, SysAFMAsk);
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 at:

http://www.delphi3000.com/articles/article_2605.asp.

Enjoy !





Please rate this article!
Skill level:
BeginnerExpert

Useful:
No!Very!

Overall rating:
PoorExcellent



Comments to this article
Write a new comment













 
Sign up to consume product discounts for Bronze memberships !

read more


  Visit our Sponsor

 

  Community Ad of
Peganza
 
   














 







     
  Copyright © 2000 - 2007 delphi3000.com - All rights reserved. Terms of use. || Privacy
delphi3000.com is a service by bluestep.com IT-Services GmbH (Vienna)