0. はじめに
CPUの数を調べることになったのですが、普段使っているsarコマンド
が使えない環境下で調べることになり、ググったのでまとめます。
なお、sysstatがインストールされ、sarの設定も完了している環境下で、sarを実行した結果はこのようになります。
本記事では下記の(4 CPU)をsarコマンドを使わずに確認する方法
を取り上げていきます。
[root@$hostname ~]# sar
Linux (略) (4 CPU)
11:03:41 LINUX RESTART (4 CPU)
11:10:01 AM CPU %user %nice %system %iowait %steal %idle
11:20:01 AM all 0.00 0.00 0.01 0.00 0.00 99.99
Average: all 0.00 0.00 0.01 0.00 0.00 99.99
[root@$hostname ~]#
1.目次
- 2.検証環境/バージョン情報
- 3.【方法①】lscpuコマンドを使ってCPUの数を調べる
- 4.【方法②】sarがやっていることを再現することでCPUの数を調べる
-
- sarはどうやってCPU[0-9]+を数えているのか
-
- sarで確認できるCPUとはなんなのか
-
- 論理プロセッサーと物理コア数、ソケット、スレッドとの関係性
- 8.【余談】sar -rコマンドとfreeコマンドの比較
-
- 参考
2.検証環境/バージョン情報
- AWS (EC2, VPC, EIP, etc)
- Red Hat Enterprise Linux release 8.1 (Ootpa)
- t2.xlarge
- ストレージはGeneral Purpose SSD (gp2)、16size (t2.xlargeを選択した場合の初期値)
- sysstat version 11.7.3
# Run system activity accounting tool every 10 minutes
*/10 * * * * root /usr/lib64/sa/sa1 1 1
# 0 * * * * root /usr/lib64/sa/sa1 600 6 &
# Generate a daily summary of process accounting at 23:53
53 23 * * * root /usr/lib64/sa/sa2 -A
3.【方法①】lscpuコマンドを使ってCPUの数を調べる
こちらの方法が一番簡単です。
[root@$hostname ~]# lscpu | grep -E '^Thread|^Core|^Socket|^CPU\('
CPU(s): 4
Thread(s) per core: 1
Core(s) per socket: 4
Socket(s): 1
[root@$hostname ~]#
4.【方法②】sarがやっていることを再現することでCPUの数を調べる
理由は次章で取り扱いますが、sarは /sys/devices/system/cpu/cpu[0-9]+
のCPUの数を数えていることが分かりました。
[root@$hostname ~]# ls /sys/devices/system/cpu/ | grep -E "cpu[0-9]+"
cpu0
cpu1
cpu2
cpu3
[root@$hostname ~]# ls /sys/devices/system/cpu/ | grep -E "cpu[0-9]+" | wc -l
4
[root@$hostname ~]#
5. sarはどうやってCPU[0-9]+を数えているのか
さて、sarはどうやってCPU[0-9]+を数えているのでしょうか。
ここではsarのソースコードをたよりに調査しました。
ソースコードはgithubで公開されています。
下記のとおりcpu[0-9]+を数えている箇所
と、cpu[0-9]+を数えている対象のパスが定義されている箇所
を抜粋します。
- cpu[0-9]+を数えている箇所
/*
***************************************************************************
* Count number of processors in /sys.
*
* IN:
* @highest If set to TRUE, then look for the highest processor number.
* This is used when eg. the machine has 4 CPU numbered 0, 1, 4
* and 5. In this case, this procedure will return 6.
*
* RETURNS:
* Number of processors (online and offline).
* A value of 0 means that /sys was not mounted.
* A value of N (!=0) means N processor(s) (cpu0 .. cpu(N-1)).
***************************************************************************
*/
int get_sys_cpu_nr(int highest)
{
DIR *dir;
struct dirent *drd;
struct stat buf;
char line[MAX_PF_NAME];
int num_proc, proc_nr = -1;
/* Open relevant /sys directory */
if ((dir = opendir(SYSFS_DEVCPU)) == NULL)
return 0;
/* Get current file entry */
while ((drd = readdir(dir)) != NULL) {
if (!strncmp(drd->d_name, "cpu", 3) && isdigit(drd->d_name[3])) {
snprintf(line, MAX_PF_NAME, "%s/%s", SYSFS_DEVCPU, drd->d_name);
line[MAX_PF_NAME - 1] = '\0';
if (stat(line, &buf) < 0)
continue;
if (S_ISDIR(buf.st_mode)) {
if (highest) {
sscanf(drd->d_name + 3, "%d", &num_proc);
if (num_proc > proc_nr) {
proc_nr = num_proc;
}
}
else {
proc_nr++;
}
}
}
}
/* Close directory */
closedir(dir);
return (proc_nr + 1);
}
出所:[https://github.com/sysstat/sysstat/blob/master/count.c]
(https://github.com/sysstat/sysstat/blob/master/count.c)
Cのコード自体はあまり詳しくないので、間違っているかもしれませんが、おそらくSYSFS_DEVCPU
配下のcpu[0-9]+
を数えているのではないかと思います。
- cpu[0-9]+を数えている対象のパス
| /* Files */ |
|:--|:--|:--|:--|
| #define STAT | | | PRE "/proc/stat" |
(略)
| #define SYSFS_DEVCPU | | PRE "/sys/devices/system/cpu" |
(略)
| #define SLASH_DEV | | PRE "/dev/" |
出所:github.com/sysstat/sysstat/blob/master/common.h
6. sarで確認できるCPUとはなんなのか
kernelのドキュメントを参考にするかぎり、sarで確認できるCPUは論理プロセッサーと考えてよいでしょう。
What: /sys/devices/system/cpu/
(略)
Description:
A collection of both global and individual CPU attributes
Individual CPU attributes are contained in subdirectories
named by the kernel'slogical CPU number
, e.g.:
/sys/devices/system/cpu/cpu#/
出所:[kernel docs sysfs-devices-system-cpu]
(https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-system-cpu)
7. 論理プロセッサーと物理コア数、ソケット、スレッドとの関係性
ここで、lscpuを実行して表示された論理プロセッサーと物理コア数、ソケット、スレッドとの関係性が気になったので調べました。
下記のブログではlscpuコマンドの実行結果を例に論理プロセッサーと物理コア数、ソケット、スレッドとの関係性についてこのように紹介しています。
論理プロセッサー = cpuソケット数 × 物理コア数/ソケット × スレッド数/物理コア数
The total number of logical cores = CPU sockets × physical cores per socket × threads per physical core. Therefore, the computer has 2 × 8 × 2 = 32 logical cores in total.
CPU(s): 32
出所: How many physical and logical CPU cores in your computer | Wei Bai 白巍
[root@$hostname ~]# lscpu | grep -E '^Thread|^Core|^Socket|^CPU\('
CPU(s): 4 # 論理プロセッサー
Thread(s) per core: 1 # スレッド数/物理コア数
Core(s) per socket: 4 # 物理コア数/ソケット
Socket(s): 1 # cpuソケット数
[root@$hostname ~]#
ところで、先日読んでいた[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識にて、sar -rコマンドとfreeコマンドの相違点
の解説がわかりやすかったので、紹介させてください。
8.【余談】sar -rコマンドとfreeコマンドの比較
freeコマンドのフィールド | sar -rコマンドのフィールド | 内容 |
---|---|---|
total | 該当なし | システムに搭載されている全メモリの量。 |
free | kbmemfree | 見かけ上の空きメモリ。 |
buff/cache | kbbuffers + kbcached | バッファキャッシュ、及びページキャッシュが利用するメモリ。システムの空きメモリが減少してきたら、カーネルによって解放される。 |
available | 該当なし | 実質的な空きメモリ。フィールドの値に、空きメモリが足りなくなってきたら解放できるカーネル内メモリ領域のサイズを足したもの。解放できるメモリにはバッファキャッシュやページキャッシュの大部分、及びその他カーネルメモリの一部が含まれる。 |
参考:[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識(一部筆者改変)
freeコマンドの実行結果
[root@$hostname ~]# free
total used free shared buff/cache available
Mem: 16256588 239692 14588360 24948 1428536 15692440
Swap: 0 0 0
sar -rコマンドの実行結果
[root@$hostname ~]# sar -r | head
Linux (略) (4 CPU)
11:03:41 LINUX RESTART (4 CPU)
11:10:01 AM kbmemfree kbavail kbmemused %memused kbbuffers kbcached kbcommit %commit kbactive kbinact kbdirty
11:20:01 AM 14581020 15690700 1675568 10.31 2716 1333316 311968 1.92 399160 993580 0
11:30:01 AM 14580936 15690652 1675652 10.31 2716 1333324 296508 1.82 399204 993332 0
11:40:01 AM 14580064 15689796 1676524 10.31 2716 1333328 315288 1.94 400016 993336 0
11:50:01 AM 14581008 15690804 1675580 10.31 2716 1333336 315288 1.94 399880 992556 20
12:00:01 PM 14580612 15690412 1675976 10.31 2716 1333344 323312 1.99 401148 991320 0
[root@$hostname ~]#
P.S. Twitterもやってるのでフォローしていただけると泣いて喜びます:)
P.P.S. fukabori.fmで聞いたこと
fukabori.fmにて、ちょうど本記事で取り扱ったcpuinfoに関連する話題があがっていたので、少し文字起こしをしました。
タイピングが追いつかず、端折っています。
Linuxは/devなどハードウェアの情報が格納されているディレクトリやファイルのように扱えるようになっている。
Linuxでいえば、cpuinfoなど
いろんな情報をファイルじゃないものをファイルのように扱うことが出来る。
そして、これはパイプという仕組みを使って後続のプログラムに、ファイルかファイルではない何かを問わず、投げることができる
全てのものをファイルのように扱い、標準入力と標準出力でデータの入り口と出口をつなげるようにする。
難しいことは後続の処理に任せよう。
設計哲学がいろんなことに繋がっている。
これを同じように扱えるというのは強い制約。
高い再利用性が発揮。