From: Greg Ercolano <erco@(email surpressed)>
Subject: Re: Multicore workstations and clever farm use
   Date: Wed, 30 Sep 2009 10:23:25 -0400
Msg# 1900
View Complete Thread (4 articles) | All Threads
Last Next
	BTW, I added some screenshots below that show how assigning
	affinity really does force renders to use specific processors.

        ** NOTE ** 
        ** Do not casually use this feature. Locking renders to particular      **
        ** physical processors usually does NOT get you what you want, and      **
        ** it can really hobble the OS from making smart scheduling decisions.  **
        **                                                                      **
        ** Just because the background renders are prevented from using         **
        ** certain procs to keep them available to the interactive user,        **
        ** it doesn't mean the machine won't still 'feel sluggish'.             **
        ** Even if cpus are 'free', they might not be able to do much if the    **
        ** machine's I/O bus is jammed with render activity.                    ** 
        **                                                                      **
        ** So in other words, the brain might be free, but the hands are busy.  **

	See "SCREENSHOTS" below.

> PROCESSOR AFFINITY
> ------------------
>       [..]
>
> 	Under Windows there's "Processor Affinity" which lets one ensure
> 	a program only uses eg. 1 processor.

	You can also force a program/render to use only 2 processors,
	or even 4. And, you can specify precisely /which/ processors
	to use.

	"Processor Affinity" is an attribute of the process, and is
	also passed down to child processes. So an affinity assigned
	to a process, it will affect all child processes it creates.

	This means if you tell rushd to have an affinity, then all
	renders rushd starts will also have that same affinity.

	So say you have a 4 processor machine, and you want to force
	rush jobs on that machine to only use physical processors
	0 and 1. This would ensure processors 2 and 3 would be completely
	available for interactive use.

	To do this, you can go into the Task Manager, right click on the
	'rushd.exe' process, and assign it an affinity for cpus #0 and #1.

	Then all renders rush starts will be forced to /only/ use those
	two processors; the other two processors will be idle, and
	available for interactive desktop use.

	CAVEAT: Keep in mind that if the render makes heavy use of the
	hard disk, ram, or network, your "interactive use" may suffer
	at the limitations of those resources. So in other words, you may
	still 'feel' slowness if your interactive use involves any of
	those resources. Remember that a program's responsiveness is not
	/only/ due to cpu availability. I/O bandwidth is also at play.

>	One way to do this is with
> 	the Windows 'start' command, eg. "start /AFFINITY <value>",
> 	where <value> indicates which processors to lock a command to..

	The DOS 'START' command is nice if you want the render script
	to control processor use.

	Note that the START command's 'AFFINITY' flag is only available
	on machines with multiple processors.

SCREENSHOTS
-----------
	Here are some screenshots that show how affinity really forces
	a process to use the processors you specify, no matter how many
	threads that process starts.

	In this case I'm running a program called 'createthread' which
	expects two parameters; a number of threads to start, and a number
	of seconds to run.

	In the following three screenshots, I'm running 'createthread 2 60'
	which starts two threads running for 60 seconds. In these 3 examples,
	I'm changing /only/ the affinity. Each screenshot includes the
	Task Manager's cpu graph, so you can see how the program makes use
	of the processors.

	Here are the three examples:

	1) No affinity (use any cpus):
	   http://seriss.com/rush/misc-docs/affinity-windows/affinity-none-threads-2.png

	2) Affinity of 1 (use cpu#1):
	   http://seriss.com/rush/misc-docs/affinity-windows/affinity-1-threads-2.png

	3) Affinity of 2 (use cpu#2)
	   http://seriss.com/rush/misc-docs/affinity-windows/affinity-2-threads-2.png

	Note that for "no affinity" both cpus are pegged 100%, total cpu usage is 100%.
	For "affinity 1", only cpu #1 is pegged, total cpu usage is only 50%.
	For "affinity 2", only cpu #2 is pegged, total cpu usage is only 50%.

	This makes it clear we can control precisely which processors
	get assigned to the process, and that regardless of the number
	of threads the process starts, only the processors with and
	affinity assigned are actually used.

> 	for instance:
> 
> 		START /AFFINITY 3 shake -exec /path/to/your.shk -t 1-69
> 
> 	..which will 'lock' the shake process to cpus #0 and #1.

	And I should add to prevent START from opening another window,
	you can use:

		START /AFFINITY 3 /B /WAIT shake -exec /path/to/your.shk -t 1-69
		                  --------

	CAVEATS: one general problem with 'START'; it has a bug where it does
	not pass the exit code of the process back to the shell. The exit code
	returned is always 0, even if the process (in this case, shake) returns
	a non-zero exit code. So if you tried to use this in a script, it would
	not be able to tell if shake failed or succeeded. Kinda annoying.

>       The /AFFINITY value is a "bit field" which breaks down this way:
> 
> 		Affinity
> 		Value		Cpu#	Binary Value
> 		--------	----	------------
> 		1 		0	0001
> 		2		1	0010
> 		3		0,1	0011
> 		4		2	0100
> 		5		0,2	0101
> 		6		1,2	0110
> 		7		0,1,2	0111
> 		:
> 		16		3	1000
> 		17		3,0	1001
> 		:
> 		etc.

	Correction -- a few mistakes in the above table
	the entries for 16 and 17 are wrong in two ways:

	First, my binary digits for 16 + 17 are wrong, 
        and second, apparently the START command's /AFFINITY
        parameter's value expects *hex*.

	So a corrected table would be:

 		Affinity
 		Value		Cpu#		Binary Value
 		--------	----		------------
 		1 		0		00001
 		2		1		00010
 		3		0,1		00011
 		4		2		00100
 		5		0,2		00101
 		6		1,2		00110
 		7		0,1,2		00111
 		8               3       	01000
                :		:		  :
		f               0,1,2,3 	01111
 		10		4		10000
 		11		4,0		10001
 		:
 		etc.

	So if you have an 8 processor machine, and want a render
	to only use the first 4 processors (0,1,2,3), then use an
	affinity of 'f'. (Hex counts 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,10,11,12..)

   [[EDIT: ADDED THE ABOVE 'NOTE' WARNING - 11/16/2010 -erco]]

Last Next