|
|
Parent Directory
| Tuning Exercises - Linux & Solaris
Brett Lee
===================================
1. On Linux, as a non-privledged user, start a long running, single-
threaded process. As root, maximize the performance of that process.
a. [brett@linux ~]$ echo $$
28121
[brett@linux ~]$ nice -n 5 top
(brett is now running top)
b. Determine the process state:
? Current execution class = ?
? Current execution priority = ?
? Current nice value = ?
? Default execution priority ?
? Current time quantum = ?
Examples of each:
+ Current execution class = TS (see below)
+ Current execution priority = 19 (see below)
[root@linux ~]# ps -elc | grep `pgrep top`
F S UID PID PPID CLS PRI ADDR SZ WCHAN TTY TIME CMD
0 S 502 28700 28121 TS 19 - 551 - pts/0 00:00:00 top
+ Current nice value = 5
[root@linux ~]# ps -el | grep `pgrep top`
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 502 28700 28121 0 80 5 - 552 - pts/0 00:00:00 top
Your wondering why this PRI is 80 and the last was 19? Much as nice
and PRI are inversely related (increase nice decreases PRI), the value
of PRI is implementation dependent - sometimes 0-based, an other times
99-based. Yeah, I agree. :)
+ Default execution priority = 24
The default execution priority is the current* execution priority plus the
current nice value.
** Pretty much: The scheduler does adjust the current execution priority.
Best to check it a few times to be sure.*
+ Current time quantum = Not available, running in TS class
[root@linux priocntl]# priocntl -d `pgrep top`
TIME SHARING PROCESSES
PID TSUPRI
28700 -5
[root@linux priocntl]#
c. Determine what could be improved:
+ Current priority - decreasing the nice value would increase the priority
[root@linux ~]# renice -20 -p `pgrep top`
28700: old priority 5, new priority -20
[root@linux ~]# ps -elc | grep `pgrep top`
0 S 502 28700 28121 TS 39 - 551 - pts/0 00:00:00 topp
[root@linux ~]# ps -el | grep `pgrep top`
0 S 502 28700 28121 0 60 -20 - 551 - pts/0 00:00:00 top
In this case, we gave 'renice' the max value but were unable to increase
the process any higher than 39.
+ Current execution class - the RR and FF classes have a max PRI of 99
[root@linux ~]# chrt -m
SCHED_OTHER min/max priority : 0/0
SCHED_FIFO min/max priority : 1/99
SCHED_RR min/max priority : 1/99
SCHED_BATCH min/max priority : 0/0
[root@linux ~]# chrt -p 28700
pid 28700's current scheduling policy: SCHED_OTHER
pid 28700's current scheduling priority: 0
Process currently in TS (Time sharing)
SCHED_OTHER is the Interactive scheduling class
BATCH is slighly less than Interactive
RR and FIFO are Real Time, but RR is Round Robin, and FIFO is FIFO
Change process to SCHED_RR (RR) class && PRI 99:
[root@linux ~]# chrt -r -p 1 28700
Verify changes:
[root@linux ~]# ps -elc | grep `pgrep top`
0 S 502 28700 28121 RR 41 - 551 - pts/0 00:00:00 top
[root@linux ~]# ps -el | grep `pgrep top`
0 S 502 28700 28121 0 58 - - 551 - pts/0 00:00:00 top
The process has now gone above the PRI 39 barrier to PRI 41 (max of 99).
In this class, the time quantum is now considered in scheduling:
[root@linux ~]# priocntl -d `pgrep top`
REAL TIME PROCESSES
PID RTPRI TQNTM
28700 1 800
[root@linux ~]#
RR is a Round Robin scheduling, with each process having an
associated time quantum. Attempt to increase both the priority and
time quantum to give some extra weight to this process over any other
RR processes.
Increase the priority and time quantum:
[root@linux ~]# chrt -r -p 10 28700
Verify:
[root@linux ~]# priocntl -d `pgrep top`
REAL TIME PROCESSES
PID RTPRI TQNTM
28700 10 800
[root@linux ~]#
Well, the PRI went up, but not the quantum. Using the Solaris syntax
to change TQNTM (see below) returns an error - need to investigate.
Alas, since this process should not be bumped off the CPU, even it is
has no time remaining in the quantum, a better solution would be to
use the FIFO class.
Change process to SCHED_FIFO (FF) class && PRI 99:
[root@linux ~]# chrt -f -p 99 28700
Verify changes (remember, FF/RR start at 40, so 99+40=139):
[root@linux ~]# chrt -p 28700
pid 28700's current scheduling policy: SCHED_FIFO
pid 28700's current scheduling priority: 99
[root@linux ~]# ps -elc | grep `pgrep top`
0 S 502 28700 28121 FF 139 - 551 - pts/0 00:00:00 top
[root@linux ~]# ps -el | grep `pgrep top`
0 S 502 28700 28121 0 -40 - - 551 - pts/0 00:00:00 top
No more time quanta to worry about:
[root@linux ~]# priocntl -d `pgrep top`
FIFO CLASS PROCESSES
PID FIPRI
28700 99
[root@linux ~]#
d. Bind the process to a single CPU
See examples in Linux_Tuning.txt (this dir)
- How to make the binding exclusive, like with Solaris Processor Sets?
e. Disable interrupts on that CPU
See examples in Linux_Tuning.txt (this dir)
f. Determine the I/O state for the process (if appropriate: ~ 2.6.18+)
If Completely Fair Queuing (CFQ) scheduler is available:
Determine by:
[root@linux ~]# cat /sys/block/sda/queue/scheduler
noop anticipatory deadline [cfq]
[root@linux ~]#
This shows that CFQ is configured in the kernel and set as the default
Check to see the current class and priority of that process:
- Current I/O class = none
- Current I/O priority = 0
Seen by:
[root@linux ~]# ionice -p `pgrep top`
none: prio 0
[root@linux ~]#
Bump up the I/O class to real time, highest priority:
[root@linux ~]# ionice --help
-n Class data (typically 0-7, lower being higher prio)
-c Scheduling class
1: realtime, 2: best-effort, 3: idle
-p Process pid
[root@linux ~]# ionice -n 0 -c 1 -p `pgrep top`
[root@linux ~]# ionice -p `pgrep top`
realtime: prio 0
[root@linux ~]#
Otherwise, determine which scheduler is available, and use the one
most appropriate for your I/O:
- Database: deadline or noop
- Multi-user server: anticipatory or deadline
- Desktop Workstation: anticipatory
* But I digress... :)
2. On Linux, as root, start a long running, single-threaded process
that will run with maximal performance.
a. Redirect all IRQs away from CPU 0
b. `nohup taskset -c 0 chrt -f -p 99 ionice -n 0 -c 1 <prog> &`
3. On Solaris, as a non-privledged user, start a long running, single-
threaded process. As root, maximize the performance of that process.
a. [brett@solaris ~]$ echo $$
4370
[brett@solaris ~]$ prstat
(brett now running prstat)
b. Determine the process state:
- Current execution class = ?
- Current nice value = ?
- Default execution priority = ?
- Current time quantum = ?
+ Current execution class = FSS
+ Default execution priority = 59
[root@solaris ~]# ps -elc | grep `pgrep prstat`
F S UID PID PPID CLS PRI ADDR SZ WCHAN TTY TIME CMD
0 S 1007 4396 4370 FSS 59 d8c08398 732 d7880f32 pts/3 0:00 prstat
+ Current nice value = 20
[root@solaris ~]# ps -el | grep `pgrep prstat`
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 1007 4396 4370 0 40 20 d8c08398 732 d7880f32 pts/3 0:00 prstat
+ Current time quantum = n/a, running in FSS class
[root@solaris ~]# priocntl -d `pgrep prstat`
FAIR SHARING PROCESSES:
PID FSSUPRILIM FSSUPRI
4396 0 0
c. Determine what could be improved:
+ Current priority - decreasing the nice value would increase the priority
[root@solaris ~]# renice -n -5 `pgrep prstat`
[root@solaris ~]# ps -el | grep `pgrep prstat`
0 S 1007 4396 4370 0 40 15 d8c08398 732 d7880f32 pts/3 0:01 prstat
Looks like the Solaris 'nice -n' is relative, while the Linux 'nice -n'
is absolute:
[root@solaris ~]# renice -n -5 `pgrep prstat`
[root@solaris ~]# ps -el | grep `pgrep prstat`
0 S 1007 4396 4370 0 40 10 d8c08398 732 d7880f32 pts/3 0:01 prstat
Using different arguments, Solaris 'nice' can be absolute, also:
[root@solaris ~]# renice -19 `pgrep prstat`
[root@solaris ~]# ps -el | grep `pgrep prstat`
0 S 1007 4396 4370 0 40 1 d8c08398 732 d7880f32 pts/3 0:01 prstat
Notice the differences in the *reported* nice values between Linux
and Solaris:
Linux = -20 thru 19
Solaris = 0 thru 39, with nice value 0 reported as 20
[root@solaris ~]# priocntl -d `pgrep prstat`
FAIR SHARING PROCESSES:
PID FSSUPRILIM FSSUPRI
4396 57 57
+ Current execution class
In the previous section, the nice value was lowered as much as possible,
resulting in the highest priority that could be acheived with 'nice'.
In order to raise it higher in the FSS class, need to use 'priocntl':
[root@solaris ~]# priocntl -s -p 59 -i pid `pgrep prstat`
FSSpriocntl: Specified user priority 59 exceeds limit 57; set to 57 (pid 4396)
[root@solaris ~]# priocntl -d `pgrep prstat`
FAIR SHARING PROCESSES:
PID FSSUPRILIM FSSUPRI
4396 57 57
[root@solaris ~]# priocntl -s -m 59 -i pid `pgrep prstat`
[root@solaris ~]# priocntl -d `pgrep prstat`
FAIR SHARING PROCESSES:
PID FSSUPRILIM FSSUPRI
4396 59 57
[root@solaris ~]# priocntl -s -p 59 -i pid `pgrep prstat`
[root@solaris ~]# priocntl -d `pgrep prstat`
FAIR SHARING PROCESSES:
PID FSSUPRILIM FSSUPRI
4396 59 59
[root@solaris ~]# priocntl -s -m -60 -i pid `pgrep prstat`
[root@solaris ~]# priocntl -s -p -60 -i pid `pgrep prstat`
[root@solaris ~]# priocntl -d `pgrep prstat`
FAIR SHARING PROCESSES:
PID FSSUPRILIM FSSUPRI
4396 -60 -60
* Need to confirm that the full range of both of these values
* actually
influence the scheduler, and how?
If changing the execution class, first see which classes are
configured:
[root@solaris ~]# priocntl -l
CONFIGURED CLASSES
==================
SYS (System Class)
TS (Time Sharing)
Configured TS User Priority Range: -60 through 60
FX (Fixed priority)
Configured FX User Priority Range: 0 through 60
FSS (Fair Share)
Configured FSS User Priority Range: -60 through 60
RT (Real Time)
Maximum Configured RT Priority: 59
Since this job should not decay (the priority should not be decreased
by the scheduler) change the execution class to FX and verify:
[root@solaris ~]# priocntl -s -c FX -i pid `pgrep prstat`
[root@solaris ~]# ps -elc | grep `pgrep prstat`
0 S 1007 4396 4370 FX 0 d8c08398 733 d7880f32 pts/3 0:07 prstat
[root@solaris ~]# ps -el | grep `pgrep prstat`
0 S 1007 4396 4370 0 99 20 d8c08398 733 d7880f32 pts/3 0:07 prstat
[root@solaris ~]# priocntl -d `pgrep prstat`
FIXED PRIORITY PROCESSES:
PID FXUPRILIM FXUPRI FXTQNTM
4396 0 0 200
Since the range is 0 - 60, set it to the max of 60 and verify:
[root@solaris ~]# priocntl -s -m 60 -p 60 -i pid `pgrep prstat`
[root@solaris ~]# priocntl -d `pgrep prstat`
FIXED PRIORITY PROCESSES:
PID FXUPRILIM FXUPRI FXTQNTM
4396 60 60 200
[root@solaris ~]# ps -elc | grep `pgrep prstat`
0 S 1007 4396 4370 FX 60 d8c08398 733 d7880f32 pts/3 0:08 prstat
[root@solaris ~]# ps -el | grep `pgrep prstat`
0 S 1007 4396 4370 0 39 0 d8c08398 733 d7880f32 pts/3 0:08 prstat
Wait, is 60 the max, or is 0 ?
[root@solaris ~]# priocntl -s -m 20 -i pid `pgrep prstat`
[root@solaris ~]# priocntl -d `pgrep prstat`
FIXED PRIORITY PROCESSES:
PID FXUPRILIM FXUPRI FXTQNTM
4396 20 20 200
[root@solaris ~]# priocntl -s -p 30 -i pid `pgrep prstat`
FXpriocntl: Specified user priority 30 exceeds limit 20; set to 20 (pid 4396)
[root@solaris ~]# ps -elc | grep `pgrep prstat`
0 S 1007 4396 4370 FX 20 d8c08398 733 d7880f32 pts/3 0:08 prstat
[root@solaris ~]# ps -el | grep `pgrep prstat`
0 S 1007 4396 4370 0 79 14 d8c08398 733 d7880f32 pts/3 0:08 prstat
Looks like 60 is. Set it to the max, increase the time quantum,
and verify:
[root@solaris ~]# priocntl -s -m 60 -p 60 -t 25000 -i pid `pgrep prstat`
[root@solaris ~]# priocntl -d `pgrep prstat`
FIXED PRIORITY PROCESSES:
PID FXUPRILIM FXUPRI FXTQNTM
4396 60 60 25000
[root@solaris ~]# ps -elc | grep `pgrep prstat`
0 S 1007 4396 4370 FX 60 d8c08398 733 d7880f32 pts/3 0:08 prstat
[root@solaris ~]# ps -el | grep `pgrep prstat`
0 S 1007 4396 4370 0 39 0 d8c08398 733 d7880f32 pts/3 0:08 prstat
+ Better - but not good enough.
Make the process be the only process that can run on a certain processor.
While were at it, make sure no interrupts are handled by that processor.
Get current processor status
[root@solaris ~]# psrinfo
0 on-line since 02/02/2009 14:39:44
1 on-line since 02/02/2009 14:39:49
2 on-line since 02/16/2009 16:33:53
3 on-line since 02/16/2009 16:33:53
Create a processor set:
[root@solaris ~]# psrset -c 3
created processor set 1
processor 3: was not assigned, now 1
Ensure interrupts are not sent to the processor in the new processor set:
[root@solaris ~]# psrset -f 1
[root@solaris ~]# psrinfo
0 on-line since 02/02/2009 14:39:44
1 on-line since 02/02/2009 14:39:49
2 on-line since 02/16/2009 16:33:53
3 no-intr since 02/16/2009 16:34:18
Bind the process to the processor set:
[root@solaris ~]# psrset -b 1 `pgrep prstat`
process id 4396: was not bound, now 1
[root@solaris ~]# psrset -q
process id 4396: 1
4. On Solaris, as root, start a long running, single-threaded process
that will run with maximal performance.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
In an effort to provide a service of value to the open source community, I've put together this website that containing many of my notes and references.
This website is not authoritative and it is certainly not without errors; it is a work in progress.
In addition to my contributions you will also find the work of others. Where the work is not mine, I have tried to indicate that, and to reference the source of the work: by citing the original author, retaining the authors' name and license wherever present, or by placing the work in a suitably named URL containg /external/ in the path. If you find any work here that should not be publically available, please send me a note and it will be removed.
As for my contributions, you are free to use any of *MY* notes or code from this website unless specifically instructed otherwise.
Brett Lee, Ph.D., President & CEO
Everything Penguin, Inc.
|
|
|