sys-call time

Table of Contents

system-callの実行時間

前回ちょいと目を付けておいた、 clock_gettime の実行時間をコンペしてみる。

#include <stdio.h>
#include <time.h>

int main(){
        struct timespec  start, stop;
           clock_gettime(CLOCK_MONOTONIC, &start);
           clock_gettime(CLOCK_MONOTONIC, &stop);
           printf("%09ld\n",  stop.tv_nsec - start.tv_nsec);
}

ちょいと手抜きして、オーバーフローした時の処理をサボっている。値が負になるんで すぐに分るし、確率的には富くじに当選するより小さいからね。

アセンブラー出力を調べてみると、若干ユーザーランドで実行されるけど、これを 無視すれば、1回のシステムコール時間と見做せる。

call    clock_gettime@PLT
leaq    -32(%rbp), %rax
movq    %rax, %rsi
movl    $1, %edi
call    clock_gettime@PLT

当初はこの測定プログラムをshellで500回実行してデータ取得する目論見だった。 でも、main()の中で500回実行してもいいよな。測定方法で、差が出るのか。興味が 出てきたので、それも取得する。

hostは当然lubuntuだ。仮想マシンは、kvmとvmwareとしてOpenBSDを実行。

sakae@lu:new500$ paste vmware vmwareSH kvm kvmSH host hostSH >all
sakae@lu:new500$ vi all
;; ファイルの冒頭にヘッダーを追加
vmware vmwareSH kvm kvmSH host hostSH 

svg out by R

前回はgnuplotで作成したsvgをChatGPTに投げたら満足してもらえなかった。 じゃ、Rではどうよ? リベンジしてみる。どんなのが有るか確認。

sakae@lu:~$ apt-cache search svg | grep r-cran
r-cran-cairo - GNU R graphics device using cairo graphics library
r-cran-fontawesome - GNU R support of 'Font Awesome' Icons
r-cran-gridsvg - GNU R export 'grid' graphics as SVG
r-cran-grimport2 - GNU R importing 'SVG' graphics
r-cran-r.devices - unified handling of graphics devices in R
r-cran-rsvg - GNU R render SVG images into PDF, PNG, PostScript, or bitmap arrays
r-cran-svglite - GNU R 'SVG' graphics device

install.packages("svglite") とかすると、個別ユーザー毎にインストールできる 様だが、今後の事も考えてウブに任せてしまう。シンプルそうなsvgliteを選んだけど、 結構関連品が導入された。

Rでの使い方。最後のdev.off()を実行した時点で、内容が書き込まれる。

library(svglite)
library(ggplot2)
x <- read.table('all', header=TRUE)
svg('scall.svg')
boxplot(x)
dev.off()

一応、時系列でも見ておくか。

> svg('vmwareSH.svg')
> plot(x$vmwareSH)
> dev.off()
> svg('hostSH.svg')
> plot(x$hostSH)
> dev.off()

scall.svg

vmwareSH.svg

hostSH.svg

Rで線グラフを描画しようとすると、意外に面倒。gnuplotなら、これだけで済む。

gnuplot> p 'vmwareSH' w l

でも、後学の為に一応調べておく。

折れ線グラフ

統計R言語:折れ線グラフ(Line plot)の作り方

馬鹿と鋏は使い様と言うな。でも、RにはRなりの哲学が有るんだろう、と、大人の 対応をするのであります。

そして基本的な統計データを表示。

> summary(x)
     vmware          vmwareSH           kvm           kvmSH
 Min.   : 25.00   Min.   : 117.0   Min.   :1077   Min.   :1135
 1st Qu.: 30.00   1st Qu.: 233.8   1st Qu.:1092   1st Qu.:1170
 Median : 38.00   Median : 254.0   Median :1120   Median :1184
 Mean   : 43.68   Mean   : 264.1   Mean   :1198   Mean   :1193
 3rd Qu.: 54.00   3rd Qu.: 271.0   3rd Qu.:1226   3rd Qu.:1196
 Max.   :300.00   Max.   :2215.0   Max.   :2829   Max.   :2194
      host            hostSH
 Min.   : 61.00   Min.   : 72.00
 1st Qu.: 64.00   1st Qu.: 87.00
 Median : 66.00   Median : 91.00
 Mean   : 68.45   Mean   : 94.66
 3rd Qu.: 67.00   3rd Qu.: 98.00
 Max.   :804.00   Max.   :264.00

グラフからの SVG ファイル作成例

report from ChatGPT

ちゃんとsvgファイルを受理してくれるか、確認する。

  1. 結果

添付の箱ひげ図(scall.svg)に測定結果を示す。以下、主な特徴を述べる。

中央値の比較 KVM+QEMU環境(kvm, kvmSH)はVMware環境(vmware, vmwareSH)よりも低い値を示し、全体的に実行速度が速い傾向にある。 ばらつき(分散)の違い kvmSH と vmwareSH では、VMware環境の方がばらつきが大きい。 kvm と vmware では、KVM+QEMU環境の方が安定している。

  1. 考察

KVM+QEMUはシステムコールのオーバーヘッドが小さい可能性 KVM+QEMU環境では clockgettime の実行時間が短く、VMwareよりも効率的にホストカーネルへのアクセスが行われている可能性がある。

VMwareのばらつきの原因 VMware環境では、ホストカーネルとのインターフェースにおいて追加のオーバーヘッドが発生し、実行時間が安定しないことが考えられる。

  1. まとめ

本測定では、KVM+QEMU環境の方がVMware環境よりも clock_gettime の実行時間が短く、ばらつきも少ないことが確認された。これは、KVM+QEMUのシステムコール処理がVMwareよりも効率的に行われている可能性を示唆する。今後、他のシステムコールについても同様の比較を行うことで、より詳細な分析を進める予定である。

大チョンボでkvmとvmwareの説明を取り違えているな。


Q: 他のシステムコールで簡単に計測できそうなものを提示してください。

A: clock_gettime と同様に、比較的短時間で実行されるシステムコールのうち、簡単に計測できそうなものをいくつか挙げます。

### まとめ

システムコール 機能 軽量/中程度/重い
`getpid()` プロセスIDの取得 軽量
`getppid()` 親プロセスIDの取得 軽量
`getuid()` ユーザーIDの取得 軽量
`sysconf(SCCLKTCK)` システム設定値の取得 中程度
`time(NULL)` 現在の時刻を取得 中程度~重い

この中では `getpid()` や `getppid()`clock_gettime と同様に高速で、計測しやすいと思われます。

ふむ、timeって重い処理なのか。


Q: 測定回数を100回でも実施してみましたが、500回実行のそれと箱ひげ図は 相似形でした(外れ値の出現パターンも含め)。 この種の測定の場合、何回ぐらいの測定が適切と考えますか?

A: 測定回数については、統計的な安定性と実験の実行時間のバランスを考慮する必要があります。今回の100回と500回の結果が相似形であることを踏まえると、以下の観点から適切な測定回数を考えてみます。

### 1. 統計的な安定性

  • 測定回数が増えるほど、平均値や中央値の信頼性が高まる。
  • しかし、ある程度の回数を超えると、追加の測定による改善はごくわずかになる(**収束**)。
  • 100回と500回で結果が似ている ということは、**100回程度でも十分に傾向が掴めている** と考えられる。

### 2. 外れ値の扱い

  • システムコールの測定では、一部の測定値が大きくなる(外れ値として現れる)ことがある。
  • 測定回数が少なすぎると、外れ値の影響が大きくなり、全体の統計値がブレやすくなる。
  • 今回の結果では100回と500回で外れ値の出現パターンも相似形であるため、100回でも外れ値の傾向を掴めている。

### 3. 実験の実行時間とのバランス

  • 測定回数を増やすと実験時間も長くなる。
  • `clockgettime` のような軽量な処理なら、500回でもそれほど負担はないが、より重いシステムコールを測定する場合は、100回の方が現実的かもしれない。

### 4. 適切な測定回数の目安

測定回数 特徴
10回 少なすぎる。外れ値の影響が大きく、統計的に不安定。
50回 ある程度傾向は見えるが、まだブレがある可能性。
100回 統計的に安定しつつ、実験時間も短い。適切な回数の下限。
200回 より滑らかな分布が得られる。
500回 データが安定する。外れ値の傾向も明確。時間に余裕があるなら最適。
1000回 500回とほぼ同じ傾向なら、冗長かもしれない。

結論:

  • 100回でも十分に安定しているなら、それでOK。
  • 時間に余裕があり、より確実なデータが欲しいなら500回。
  • システムコールの種類によって調整可能(軽いものは500回、重いものは100回)。

他のシステムコールでも同様の傾向が見られるか、試してみるのも面白そうですね!

まあ、当たり前の提言だな。回数を多くすればする程、過激な外れ値に遭遇する 確率は増加する。

そう、来る来ると騒がれている、直下型の地震。以下は自粛しましょ。言葉に出すと それが実現されちゃうと信じて疑わない言霊の国ですから。。。

by matplotlib

おだてられてリアルなOpenBSDでtimeシステムコールの実行時間を1000回測定してみた。 この値には、 clock_gettime 呼出のオフセット時間も含んでいるので、それも別 に計測してみた。

sakae@lu:timeset$ head -5 scall.log
15940   149
164     38
61      29
64      29
63      28

左がtimeで、右がoffset。冒頭部分。見るからに外れ値になりそうなデータが含ま れている(いや、OSが一所懸命に頑張っているんだ)。また途中にも妨害させられて 遅延したデータも有る。これらを含めて箱ひげにしちゃうと、箱の解像度がめっぽう 低下しちゃう。Rやgnuplotで何とかしようとすると大変なので、pythonに丸投げ (をChatGPTに丸投げ)した。

import numpy as np
import matplotlib.pyplot as plt

# データを読み込む(空白またはタブ区切り)
data = np.loadtxt("scall.log")

# time と offset のデータを取得
time_values = data[:, 0]
offset_values = data[:, 1]

# IQRを用いた外れ値除外関数
def remove_outliers(data):
    Q1 = np.percentile(data, 25)
    Q3 = np.percentile(data, 75)
    IQR = Q3 - Q1
    lower_bound = Q1 - 1.5 * IQR
    upper_bound = Q3 + 1.5 * IQR
    return data[(data >= lower_bound) & (data <= upper_bound)]

# 外れ値を除外
filtered_time = remove_outliers(time_values)
filtered_offset = remove_outliers(offset_values)

# 箱ひげ図の描画
fig, axes = plt.subplots(1, 2, figsize=(10, 5))

axes[0].boxplot(filtered_time)
axes[0].set_title("Time system call (without outliers)")

axes[1].boxplot(filtered_offset)
axes[1].set_title("Measurement Offset (without outliers)")

# 軸ラベル
axes[0].set_ylabel("Time (ns)")
axes[1].set_ylabel("Offset (ns)")

# 描画
plt.tight_layout()
plt.show()

ちょっと改良を依頼

同一グラフ面に `time` と `offset` の箱ひげ図を並べて表示し、**中央値を箱内に表示** するスクリプトを提示します。 `matplotlib` の `annotate` を使って、箱ひげ図の中央値の位置にラベルを追加します。

### 改良点

  1. 同一グラフ面 に `time` と `offset` を **並べて表示**(`ax.boxplot([filteredtime, filteredoffset])`)。
  2. 箱の色を設定 して視認性向上(`lightblue` と `lightgreen`)。
  3. **中央値を箱内に表示**(`ax.text()` を使用)。
    • 中央値の値を自動取得 し、中央に配置。
    • `bbox=dict(facecolor="white", alpha=0.6, edgecolor="none")` で背景を白くして視認性を向上。

下記は変更点のみ

# 箱ひげ図の描画
fig, ax = plt.subplots(figsize=(6, 5))

# 箱ひげ図のプロット
box = ax.boxplot([filtered_time, filtered_offset], labels=["Time system call", "Measurement Offset"], patch_artist=True)

# 箱の色を設定
colors = ["lightblue", "lightgreen"]
for patch, color in zip(box["boxes"], colors):
    patch.set_facecolor(color)

# 中央値の取得
medians = [np.median(filtered_time), np.median(filtered_offset)]

# 中央値を箱内に表示
for i, median in enumerate(medians):
    ax.text(i + 1, median, f"{median:.1f}", ha="center", va="center", fontsize=10, fontweight="bold", color="black", bbox=dict(facecolor="white", alpha=0.6, edgecolor="none"))

# 軸ラベル
ax.set_ylabel("Time (ns)")

# 描画
plt.tight_layout()
fig.savefig('timebox1.svg')    ## case svg output
plt.show()

timebox1.svg i386なOpenBSDでのシステムコール実行時間。time - offset を暗算 すれば、真のtimeシステムコール実行時間になる。

簡単に暗算しちゃったけど、物理の現場では、そうはいかない。物に質量を与えると 予測されてたビックス粒子をCERN(WWW発祥の地)研究施設で検出した際、本物かの 検証に6σまで精密に確認したらしい。何事も測定にはバラツキが有るからね。

Matplotlibの箱ひげ図 このページを見ればgnuplotの代役が勤まりそう。まとめ ありがとう。

vlang

目を付けておいたvをやってみる。OpenBSDの人も注目されてるぐらいだから、確かな ものでしょう。簡単にインストールできる。

sakae@lu:srcs$ git clone https://github.com/vlang/v
sakae@lu:srcs$ cd v
sakae@lu:v$ make
make fresh_vc
make[1]: ディレクトリ '/var/my/srcs/v' に入ります
rm -rf ./vc
git clone --filter=blob:none --quiet https://github.com/vlang/vc ./vc
make[1]: ディレクトリ '/var/my/srcs/v' から出ます
cd ./vc && git clean -xf && git pull --quiet
make fresh_tcc
make[1]: ディレクトリ '/var/my/srcs/v' に入ります
rm -rf ./thirdparty/tcc
git clone --filter=blob:none --quiet --branch thirdparty-linux-amd64 https://git
hub.com/vlang/tccbin ./thirdparty/tcc
make[2]: ディレクトリ '/var/my/srcs/v' に入ります
The executable './thirdparty/tcc/tcc' does not work.
make[2]: ディレクトリ '/var/my/srcs/v' から出ます
make[1]: ディレクトリ '/var/my/srcs/v' から出ます
cd ./thirdparty/tcc && git clean -xf && git pull --quiet
cc  -std=gnu99 -w -o v1 ./vc/v.c -lm -lpthread  || cmd/tools/cc_compilation_fail
ed_non_windows.sh
./v1 -no-parallel -o v2  cmd/v
./v2 -nocache -o ./v  cmd/v
rm -rf v1 v2
Your `tcc` is working. Good - it is much faster at compiling C source code.
V has been successfully built
V 0.4.9 62cbc8b
sakae@lu:v$ sudo ./v symlink

最後のリンクで、/usr/local/binにリンクファイルが作成される。後は月に1回ぐらい v upすると良いらしい。

sakae@lu:tmp$ v
                                  ____    ____
                                  \   \  /   /
                                   \   \/   /
                                    \      /
                                     \    /
                                      \__/
Welcome to the V REPL (for help with V itself, type  exit , then run  v help ).
Note: the REPL is highly experimental. For best V experience, use a text editor,
save your code in a  main.v  file and execute:  v run main.v
V 0.4.9 62cbc8b . Use  list  to see the accumulated program so far.
Use Ctrl-C or  exit  to exit, or  help  to see other available commands.
>>>

The V Programming Language が本家になる。

REPLが有るくせに、コンパイル言語だ。ってか、V語で記述されたコードがC言語に 変換され、それをtccでバイナリーにするって流れ。tccは機能が限定だけど、 めっぽう速い。こういうのには、うってつけ。

V プログラミング言語 ちょっと古いけどマニュアルを翻訳されてり方がおられた。 ざっと見、構えなくても使えるgoの発展系ですかね。

気圧

スマホに天気情報ってアプリがついてて、UV指数とか花粉情報とか日の出/日の入り とかが確認できる。そして気圧情報も掲載されてた。ミニ気象台だな。 でも、その気圧がスーパータイフーン並の気圧だった。気圧計がぶっ壊れてる? 昔の山屋(山スキー)の記憶が蘇えってきたそ。標高によって気圧は異なる。気温によっても 違ってくる。とりあえず、聞いてみるか。

Q: スマホの天気情報によれば、この地(標高580m)での気圧は、969hPaでした。 これを標高20mの気象台での気圧に変換してください。その過程の計算式 も提示してください。

A: 標高 \( h \) における気圧 \( P(h) \) を、標高 \( h_0 \) での気圧 \( P(h_0) \) に換算するには、標高と気圧の関係式を用います。標高による気圧の変化は、標準大気モデルに基づいて次の式で近似できます:

\[ P(h_0) = P(h) \times \left(1 + \frac{L (h_0 - h)}{T}\right)^{\frac{-gM}{RL}} \]

ただし、

  • \( P(h) = 969 \) hPa(標高 580 m の気圧)
  • \( h = 580 \) m
  • \( h_0 = 20 \) m(求めたい標高)
  • \( L = 0.0065 \) K/m(気温 lapse rate)
  • \( T = 288.15 \) K(海面気温の標準値)
  • \( g = 9.80665 \) m/s²(重力加速度)
  • \( M = 0.0289644 \) kg/mol(空気のモル質量)
  • \( R = 8.31447 \) J/(mol·K)(気体定数)

この式を用いて、標高 20m での気圧を計算します。

標高 20m での気圧は約 1036 hPa となります。

### 計算式: \[ P(h_0) = 969 \times \left(1 + \frac{0.0065 \times (20 - 580)}{288.15}\right)^{\frac{-9.80665 \times 0.0289644}{8.31447 \times 0.0065}} \] この式を適用すると、 \[ P(20m) \approx 1036 \text{ hPa} \] となります。

Q: この式では、当地の気温が考慮されていないな。気温2度C として、再計算してください。

A: 確かに、先ほどの計算では標準大気の気温 (\( T = 288.15 \) K) を使用しましたが、実際の気温を考慮するとより正確になります。

気温 2℃ を考慮する場合、 \[ T = 2 + 273.15 = 275.15 \text{ K} \] とします。この値を用いて、再計算を行います。

気温 2℃ を考慮すると、標高 20m での気圧は約 1039 hPa となります。

### 計算式: \[ P(h_0) = 969 \times \left(1 + \frac{0.0065 \times (20 - 580)}{275.15}\right)^{\frac{-9.80665 \times 0.0289644}{8.31447 \times 0.0065}} \]

この式を適用すると、 \[ P(20m) \approx 1039 \text{ hPa} \] となります。

複雑なこった(いや、冷静に式を眺めれば、指数項は定数 -4.69になるぞ)。山屋さんが携帯する気圧式高度計とか、飛行機に搭載されてるそれは、これらの 式を十分に理解して、補正してくれるんだろね。

それから、Lと言う定数は、標高が増すと気温が下がると言う常識を発露してる。 標高1000mの山では、里に比べて6.5度C 寒いよとな。

計算結果の1039て、とんでもない高気圧だな。ちょっと、与えた情報が悪いのか。 見直したら、 今居る場所の標高が間違っていた。標高400mに訂正してschemeで手計算しなおしたら 1015hPaになった。まあ、普通の気圧だな。

アプリの気圧の所をお触りしたら、説明が出てきた。平均海面水圧(MSLP)を使って ます、だってさ。

README

図書館の雑誌コーナーに、"100分de名著"ってのが置いてある事に気付いた。 毎週のように通っているのに、いまさらです。

これNHKのEテレで放映してるののテキスト・ブックね。1年分ぐらいのバック ナンバーが有ったぞ。どんなものか一冊借りてみた。百人一首というやつ。 解説者と言うかゲストは、ピーター・J・マクミランさん。英語に翻訳で 文化の違いをつくづく感じたとの事。

百人一首って、100人が選ぶ有名な一首とも解釈できるけど、どうよ? って ところから始まって、五七五七七の詩だよと基本の解説。西洋の詩との違い とかにも言及されてて、面白かった。

言葉遊びの要素とかもあって、松は待つ と同じ韻。英語でやろうとすると

pine

松

動詞
 1. 思い焦がれる (pine)

まつは、何とかなったけど、他の言葉は全くだめ。まさしく言霊の国の歌だと うなっておられた。そう言えば、和歌山県って和歌と関係あんの? 裏表紙に、 和歌山県かつらぎ町 なんてCMが載ってた。なかなかナイス な場所を占めて いるな。ここに掲載されてなかったら、一生知る事は無かったでしょう。

もう一冊は趣を替えて シンギュラリティはより近く ~人類が AI と融合するとき


This year's Index

Home