CPU to core mapping

A frequently asked question among users of CMT platforms is "How do I know which CPUs share a core?". For most users, the best answer is, "don't worry about it", because Solaris does a good job of assigning software threads to CPUs and spreading them across cores such that the utilization of hardware resources is maximized. However, knowledge of the mapping is helpful to users who want to explicitly manage the assignment of threads to CPUs and cores, to squeeze out more performance, using techniques such as processor set binding and interrupt fencing.

For some processors and configurations, the core can be computed as a static function of the CPU ID, but this is not a general or easy-to-use solution. Instead, Solaris exposes this in a portable way via the "psrinfo -pv" command, as shown in this example on an M5000 server:

    % psrinfo -pv
    
    The physical processor has 2 cores and 4 virtual processors (0-3)
      The core has 2 virtual processors (0 1)
      The core has 2 virtual processors (2 3)
        SPARC64-VI (portid 1024 impl 0x6 ver 0x90 clock 2150 MHz)
    The physical processor has 2 cores and 4 virtual processors (40-43)
      The core has 2 virtual processors (40 41)
      The core has 2 virtual processors (42 43)
        SPARC64-VI (portid 1064 impl 0x6 ver 0x90 clock 2150 MHz)
    

The numbers in parenthesis are the CPU IDs, as known to Solaris and used in commands such as mpstat, psradm, etc. At this time, there are no supported programmatic interfaces to get this information.

Now for the confusing part. Unfortunately, "psrinfo -pv" only prints the core information on systems running OpenSolaris or Solaris Express, because psrinfo was enhanced by this CR:

    6316187 Need interface to determine core sharing by CPUs
which was never backported to a Solaris 10 update. I cannot predict when or whether this will be done. However, on Solaris 10, you can see core groupings using the unstable and less friendly kstat interface. Try this script, which I have named showcores:
    #!/bin/ksh
    kstat cpu_info | \\
        egrep "cpu_info |core_id" | \\
        awk \\
            'BEGIN { printf "%4s %4s", "CPU", "core" } \\
             /module/ { printf "\\n%4s", $4 } \\
             /core_id/ { printf "%4s", $2} \\
             END { printf "\\n" }'
    

    % showcores
     CPU core
       0   0
       1   0
       2   2
       3   2
      40  40
      41  40
      42  42
      43  42
    

The core_id extracted from the kstats is arbitrary, but CPUs with the same core_id share a physical core. Beware that the name and semantics of kstats such as core_id are unstable interfaces, which means they are not documented, not supported, and are subject to change.

Comments:

Unfortunately, this is also broken on Solaris 10:

datum:~: uname -i
SUNW,Sun-Fire-T200

datum:~: kstat cpu_info | \\
? egrep "cpu_info |core_id" | \\
? awk \\
? 'BEGIN { printf "%4s %4s", "CPU", "core" } \\
? /module/ { printf "\\n%4s", $4 } \\
? /core_id/ { printf "%4s", $2} \\
? END { printf "\\n" }'
CPU core
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
11 11
12 12
13 13
14 14
15 15
16 16
17 17
18 18
19 19
20 20
21 21
22 22
23 23
24 24
25 25
26 26
27 27
28 28
29 29
30 30
31 31

Posted by Eric Sturdivant on January 08, 2009 at 08:37 AM EST #

Try running a more recent patch level of Solaris 10. I recall there
was a bug in computing the core_id kstat, but I don't have a CR number.
On my T2000 running Solaris 10 at patch level 137137-09 (aka update 6),
the script works:

% uname -a
SunOS lab-t2000-a 5.10 Generic_137137-09 sun4v sparc SUNW,Sun-Fire-T200
% showcores
CPU core
0 258
1 258
2 258
3 258
4 261
5 261
6 261
7 261
...

Thanks for your observation.

Posted by Steven Sistare on January 09, 2009 at 01:05 AM EST #

Designed for high availability:
Predictive Self Healing is a key feature in the Solaris 10 OS that helps you increase system and service availability. It automatically detects, diagnoses, and isolates system and software faults before they cause downtime. And it spans the full range from diagnosis to recovery on SPARC, AMD Opteron™ and Athlon, and Intel® Xeon® and Core Duo processor-based systems.

Will Solaris 10 support the new Intel i7 Quad Core processors?
Will Solaris 10 make use of them ?

I am so done with windows (All), I am looking at new Unix/Linux distributions
and would like to know if the OS will support it.
I did find 1 entry in the Hardware guide for a Gigabyte Motherboard with the x58 chipset.

Posted by Richard Ennis on May 16, 2009 at 04:36 AM EDT #

Thanks for the great info! This is exactly what I needed for a licensing project.

Posted by Robert Peebles on July 16, 2009 at 01:40 PM EDT #

Why does this have to be so difficult? So many of software vendors license based on cores, you would think there would be a simple command that gives you a core count or at least a consistant output from psrinfo. While the kstat command is "unstable", it seems to be the only method of performing this task without making assumptions based on the server model like "memconf" does.

Here's my stab at a cpu inventory script that seems to work pretty well for us:

#!/usr/bin/perl

$hostname=`/usr/bin/uname -n`;
chomp $hostname;

$kstat="/usr/bin/kstat -m cpu_info";
$core_id=0;

open (KSTAT, "$kstat |") || die "Can not open $kstat\\n\\n$!\\n\\n";
while (<KSTAT>) {
$line=$_;
chomp $line;

# Get the CPU instance number
if ($line =~ /\^module:/ ) {
$instance = $line;
$instance =~ s/\^.\*instance:\\s+//;
$instance =~ s/\\s+$//;
push (@INSTANCES, "$instance");
}
# Get the CPU chip id
if ($line =~ /chip_id/ ) {
$chip_id = $line;
$chip_id =~ s/\^.\*chip_id\\s+//;
$CHIPS["$instance"]=$chip_id;
}
# Get the CPU speed
if ($line =~ /clock_MHz/ ) {
$speed = $line;
$speed =~ s/\^.\*clock_MHz\\s+//;
$SPEED["$instance"]=$speed;
}
# Get the CPU type
if ($line =~ /implementation/ ) {
$implementation = $line;
$implementation =~ s/\^.\*implementation\\s+//;
$implementation =~ s/\\s\\(.\*\\)//;
$TYPE["$instance"]=$implementation;
}
# Get the CPU core id
if ($line =~ /core_id/ ) {
$core_check=1;
$core_id = $line;
$core_id =~ s/\^.\*core_id\\s+//;
$CORES["$instance"]=$core_id;
}
}

# IF the system is multi-threaded, lets only print unique cores
if ( $core_check == 1 ) {
foreach $instance (@INSTANCES) {
chomp $instance;
if ( $CORES["$instance"] ne "$last_core" ) {
push (@TO_PRINT, "$instance");
}
$last_core=$CORES[$instance];
}
} else {
foreach $instance (@INSTANCES) {
chomp $instance;
$CORES[$instance]=$CHIPS[$instance];
}
@TO_PRINT=@INSTANCES;
}

foreach $instance (@TO_PRINT) {
chomp $instance;
print "$hostname|NA|$instance|$CORES[$instance]|$SPEED[$instance]|NA|$TYPE[$instance]\\n";

}

Posted by Anonymous on October 01, 2009 at 06:56 AM EDT #

The OpenSolaris psrinfo is available as perl script and works very well:

http://hub.opensolaris.org/bin/download/Community+Group+performance/files/psrinfo.pl

Here's my output on a T5220:

perl psrinfo.pl -pv
The physical processor has 4 cores and 13 virtual processors (-50)
The core has 4 virtual processors (0-3)
The core has 3 virtual processors (16-18)
The core has 3 virtual processors (32-34)
The core has 3 virtual processors (48-50)
UltraSPARC-T2 (clock 1415 MHz)

Posted by Vikram Das on October 29, 2009 at 09:07 AM EDT #

Try this:
echo "`hostname` has `kstat cpu_info | grep core_id | uniq | wc -l` cores"

Posted by Moe Obeid on July 15, 2010 at 09:42 AM EDT #

Hello All,

Great info. This is what exactly I was looking for. helped me very much. Thanks to all.

Posted by Kumaresan M on March 07, 2011 at 06:35 AM EST #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Steve Sistare

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today