ablog

不器用で落着きのない技術者のメモ

vmstat でタイムスタンプを表示する

vmstat: Support for timestamps with '-t' & fix for '-wd'
From now the vmstat can append a timestamp to each line in the
VMSTAT and DISKSTAT mode. You can achieve that with the '-t'
switch.
The '-w' switch now works in the DISKSTAT mode too.

vmstat: Support for timestamps with '-t' & fix for '-wd' (4fcd56bf) · Commits · procps-ng / procps · GitLab

これ以降 vmstat は -t オプションでタイムスタンプを表示できるようになっている。

$ vmstat -V
procps version 3.2.8
$ vmstat -t 5
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------ ---timestamp---
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 59579072 735596 280408    0    0     0     0   10    2  0  0 100  0  0	2018-01-08 07:33:15 UTC
 0  0      0 59579072 735596 280408    0    0     0     0   30   34  0  0 100  0  0	2018-01-08 07:33:20 UTC
 0  0      0 59578932 735596 280408    0    0     0     0   29   34  0  0 100  0  0	2018-01-08 07:33:25 UTC

この機能追加が入る前のバージョンの vmstat でも以下のように awk などでタイムスタンプを追加してやるとよい。

$ vmstat 5|awk '{print strftime("%Y-%m-%d %H:%M:%S"), $0}'
2018-01-08 07:35:47 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
2018-01-08 07:35:47  r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
2018-01-08 07:35:47  1  0      0 59579072 735668 280420    0    0     0     0   10    2  0  0 100  0  0
2018-01-08 07:35:52  0  0      0 59579072 735668 280420    0    0     0     5   69   68  0  0 100  0  0
2018-01-08 07:35:57  0  0      0 59579072 735668 280420    0    0     0     0   32   38  0  0 100  0  0

なお、パイプで tee コマンドに渡すなどすると、awk がバッファリングしてすぐに表示されないので、"fflush()" でフラッシュしてやる。詳しくは下記 URL 参照。

$ vmstat 5|awk '{print strftime("%Y-%m-%d %H:%M:%S"), $0;fflush()}'|tee -a vmstat_20180109.log

vmstat を含む procps プロジェクトのソースコードprocps-ng / procps · GitLab で読むことができる。

Linux で clocksource が xen と tsc で gettimeofday(2) の性能を比較する

Linux で clocksource が xentsc で gettimeofday(2) の性能を比較したメモ。

テストプログラムをコンパイルする

  • 1億回 gettimeofday(2) を実行するテストプログラム(gettimeofday.c)
#include <stdio.h>
#include <sys/time.h>
int main(void)
{
	struct timeval tv;
        int count;
        for (count = 1; count <= 10000000; count++) {
                gettimeofday(&tv, NULL);
        }
	return 1;
}
$ gcc -o gettimeofday gettimeofday.c

性能比較する

xen の場合
  • clocksource を確認する。
$ cat /sys/devices/system/clocksource/clocksource0/current_clocksource
xen ★
  • テストプログラムを実行する。
$ time ./gettimeofday

real	0m8.815s
user	0m2.196s
sys	0m6.616s ★カーネルモードにコンテキストスイッチするため sys が高い
TSC の場合
  • clocksource を TSC に変更する。
$ sudo su -
Last login: Sun Jan  7 23:49:22 UTC 2018 on pts/0
# echo "tsc" > /sys/devices/system/clocksource/clocksource0/current_clocksource
# exit
logout
$ cat /sys/devices/system/clocksource/clocksource0/current_clocksource
tsc ★クロックソースが tsc の場合
  • テストプログラムを実行する。
$ time ./gettimeofday

real	0m0.180s ★ 約50倍速い
user	0m0.176s
sys	0m0.000s ★ vDSO でユーザーモードで実行されるため

Linux で clocksource を変更する方法

Red Hat Enterprise Linux 6、 7 での clocksource の変更手順。
他のバージョンについてなどは How to change the clock source in the system - Red Hat Customer Portal 参照。

確認方法

  • 現在の clocksource を確認する。
$ cat /sys/devices/system/clocksource/clocksource0/current_clocksource
xen
  • 選択可能な clocksource を確認する。
$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource
xen tsc

変更方法

  • 動的に変更する(再起動すると元に戻る)
# echo "tsc" > /sys/devices/system/clocksource/clocksource0/current_clocksource
  • 永続的に変更する(groub.conf で "clocksource=tsc" のように指定する)
title Red Hat Enterprise Linux Server (2.6.32-71.18.2.el6.x86_64)
        root (hd0,0)
        kernel /vmlinuz-2.6.32-71.18.2.el6.x86_64 ro root=LABEL=/ crashkernel=auto clocksource=tsc
        initrd /initramfs-2.6.32-71.18.2.el6.x86_64.img