Re: [RESEND][RFC] lscpu - CPU architecture information helper

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jul 8, 2008 at 14:54, Cai Qian <qcai@xxxxxxxxxx> wrote:
> Hi,
>
> Thanks for all your comments. I have rewritten the tool in C, and made
> several changes. The new output is like the following,
>
> $ /usr/bin/lscpu
> CPU(s):                8
> Thread(s) per core:    2
> Core(s) per socket:    2
> CPU socket(s):         2
> NUMA node(s):          1
> Vendor ID:             GenuineIntel
> CPU family:            Itanium 2
> Model:                 0
> CPU MHz:               1598.000005
> L1d cache:             16K
> L1i cache:             16K
> L2d cache:             256K
> L2i cache:             1024K
> L3 cache:              12288K
>
> $ /usr/bin/lscpu -p
> #The following is the parsable format, which can be fed to other
> #programs. Each different item in every column has a unique ID
> #starting from zero.
> #
> #CPU,Core,Socket,Node,L1d,L1i,L2d,L2i,L3
> 0,0,0,0,0,0,0,0,0
> 1,0,0,0,0,0,0,0,0
> 2,1,0,0,1,1,1,0,0
> 3,1,0,0,1,1,1,0,0
> 4,2,1,0,2,2,2,1,1
> 5,2,1,0,2,2,2,1,1
> 6,3,1,0,3,3,3,1,1
> 7,3,1,0,3,3,3,1,1
>
> If you are happy about the output. I'll tidy up the code a little bit,
> do more testing, and create a manpage.
>
> Thanks,
> CaiQian
>
> /*
>  lscpu - CPU architecture information helper
>  Copyright (C) 2008 Cai Qian <qcai@xxxxxxxxxx>
>
>  This program is free software: you can redistribute it and/or modify
>  it under the terms of the GNU General Public License as published by
>  the Free Software Foundation, either version 3 of the License, or
>  (at your option) any later version.
>
>   This program is distributed in the hope that it will be useful,
>   but WITHOUT ANY WARRANTY; without even the implied warranty of
>   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>   GNU General Public License for more details.
>
>   You should have received a copy of the GNU General Public License
>   along with this program.  If not, see <http://www.gnu.org/licenses/>.
> */
>
> #include <ctype.h>
> #include <dirent.h>
> #include <err.h>
> #include <errno.h>
> #include <fcntl.h>
> #include <getopt.h>
> #include <math.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <sys/stat.h>
> #include <sys/types.h>
> #include <sys/utsname.h>
> #include <unistd.h>
>
> #define BASE 2
> #define CACHE_MAX 100
> #define MARK_LABEL ":"
>
> /* Calculate on number of silbings from a decimal mapping. */
> int
> sibling (double mapping)
> {
>  int i = 0, j = 0;
>
>  while (mapping != 0)
>    {
>      i++;
>      j = (int) (log (mapping) / log (BASE));
>      mapping -= pow (BASE, j);
>    }
>
>  return i;
> }
>
> /* Convert hexdecimal number from a mapping file to decimal.*/
> double
> decimal (char *file)
So you extend your supported number of cpus from 32 to 52, great. You
should either look inside the kernel code, kernel documentationm or
into the libbitmask(3) from Paul Jackson/SGI [1].

>  /* number of CPUs */
>  for (;;)
>    {
>      sprintf (buf, "%s/cpu/cpu%d", syspath, cpu);
>      if (stat (buf, &info) == 0)
>        cpu++;
>      else
>        break;
>    }
Again, no support for holes in the cpu range. But I'm currently unsure
if holes are actually possible. What about using readdir and check for
a cpu%d pattern of the dir name with sscanf?

>  if (have_topology)
>    {
>      /* number of threads */
>      sprintf (buf, "%s/topology/thread_siblings", cpu0path);
>      thread = sibling (decimal (buf));
>
>      /* number of cores */
>      sprintf (buf, "%s/topology/core_siblings", cpu0path);
>      core = sibling (decimal (buf)) / thread;
>
>      /* number of sockets */
>      socket = cpu / core / thread;
Sockets can also be counted by the physical_package_id topology
attribute. But some older architectures have a bug with this [2].

>  if (have_node)
>    {
>      /* number of NUMA node */
>      for (;;)
>        {
>          sprintf (buf, "%s/node/node%d", syspath, node);
>          if (stat (buf, &info) == 0)
>            node++;
>          else
>            break;
>        }
>
>      /* information about how nodes share different CPUs */
>      sprintf (buf, "%s/cpumap", node0path);
>      nodecpu = sibling (decimal (buf));
What about nodes >0, in node0/cpumap are only the cpus from node0, you
should also check the cpumaps from the other nodes.

By the way, you check only cpu0 for topology and cache infos, I don't
know if it is possible to have cpus of different topology/cache types
in one system. Anyone?

Regards
Bert

[1] http://oss.sgi.com/projects/cpusets/
[2] http://lkml.org/lkml/2008/5/13/429
--
To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux