2011年12月24日土曜日

Fedora 16 で久々に Xen を試してみる

KVM の登場で、ほとんど触ることが無くなっていた Xen ですが、Linux 3.0 以降で Dom0 動作可能になっており、Fedora 16 なら簡単に Xen を動かせるので、試してみました。

■準備
yum install xen を実行して、Xen 関連のパッケージを導入します。grub2 のメニューは、自動で追加されるので、特に何もすることはなく、導入は簡単でした。再起動して、
Linux, with Xen 4.1 and Linux 3.1.2-1.fc16.x86_64
このように with Xen 4.1 がついたメニューを選択して起動すれば OK でした。

■実験内容
ホストには Fedora 16 x86_64 、ゲストには CentOS 6.2 x86_64 を使い、Xen 準仮想化、Xen 完全仮想化、KVM の3つの場合で、パフォーマンスがどの程度違うものかを比較。ハードは、ThinkPad X301 (Core2 Duo U9400 1.40GHz) です。
個人設備の関係上、ディスク性能が貧弱なため、ベンチマークには姫野ベンチを使いました。
なお、CentOS 6 では、DomU 用カーネルというのは無いので、カーネルの種類を切り替えるようなことはしなくて済みます。CentOS 5 の場合は、準仮想化で動くには xen カーネルを使う必要がありましたし、CentOS 4 では xenU カーネルを使う必要がありました。

■実験結果
単位MFLOPS
 84.511594  Xen 完全仮想化 ゲスト (CentOS 6.2 x86_64)
 86.336558  Xen 準仮想化 ゲスト   (CentOS 6.2 x86_64)
 96.247089  Xen Dom0   (Fedora16 x86_64、ゲストとは OS 環境が異なります)
106.986019  KVM ゲスト (CentOS 6.2 x86_64)
101.272400  KVM ホスト (Fedora16 x86_64、ゲストとは OS 環境が異なります)
姫野ベンチの結果のみですが、KVM のほうがパフォーマンス (CPU, メモリ周り) が良いという結果になりました。

■所感
ベンチを実行する前の段階で、体感上 Xen のほうがもっさりしていると感じました。普段、ネイティブ環境 (KVM ホスト側) で作業して、たまに仮想マシンを使うという私の利用形態だと、わざわざ性能劣化した Dom0 で通常作業はしたくないですし、Xen のメリットは全く無いという感想を持ちました。また個人的に Xen で気になる点として、Dom0 上で標準の性能ツール (sar 等) を採取しても、Xen ゲストの性能データを得られない点が挙げられます。KVM であれば、ホスト側の sar には、ゲストの値も計上されます。また、KVM ゲストは、KVM ホストからはプロセスに見えるため、top コマンドでも、KVM ゲスト毎の負荷状況を簡単にモニターできます。

■個人的結論
現時点で、Xen を使うメリットは全くないと感じました。Hyper-V のハイパーバイザー部分は Xen と共有しているそうですし、Oracle VM も Xen ベースだとのこと。それらがいくらチューニングしようとも、KVM よりもレイヤーが厚い分だけ、性能面で不利なのではないかと思われます。

2012-02-19追記
古い VT(CPUの仮想化支援機能)非対応のPC(P4 3.6G)を再利用しようとして、そんな時には Xen が役立つと再認識しました。Fedora 16 で (KVM無しの) QEMU を試しましたが、実用的に使うには無理がありました。QEMU では、ゲストが起動するのに 30 分かかるのが、Xen であれば許せる時間内(数分)でゲスト起動できました。

2011年12月18日日曜日

ksh で扱える整数の上限

bash と tcsh について、扱える整数の上限を調べましたが、さらに ksh についても調べてみました。
#!/bin/ksh93

function test_int_limit {
        typeset i=2147483646
        echo -e "INT_MAX-1 = "$i
        let i++
        echo -e "INT_MAX   = "$i
        let i++
        echo -e "INT_MAX+1 = "$i
echo
        i=4294967294
        echo -e "ULONG_MAX-1 = "$i
        let i++
        echo -e "ULONG_MAX   = "$i
        let i++
        echo -e "ULONG_MAX+1 = "$i
echo
        i=999999999999999998
        echo "i = "$i
        let i++
        echo "i+1 = "$i
        let i++
        echo "i+2 = "$i
echo
        i=9223372036854775806
        echo -e "LLONG_MAX-1 = "$i
        let i++
        echo -e "LLONG_MAX   = "$i
        let i++
        echo -e "LLONG_MAX+1 = "$i
echo
}

test_int_limit
ksh について、何点か補足メモ、、、

(1) 関数定義する場合、function キーワードを使用して、関数名の後ろに () はつけません。
つけると構文エラーになります。
(2) ローカル変数を使うには、typeset を指定します。
bash にも typeset がありますが、あちらは、Obsolute (廃止) とされています。
(3) 関数定義は、(1) 以外にも旧来の 関数名() { ... } という記載方法もある。
しかし、その場合に typeset によるローカル変数指定が機能しません。
なので、ksh の場合は (1) の書き方を使いましょう。

テストスクリプトを実行した結果が、下記です。
# uname -a                                                                                                                                                                      
Linux my41 2.6.18-274.12.1.el5 #1 SMP Tue Nov 29 13:37:46 EST 2011 x86_64 x86_64 x86_64 GNU/Linux
# ksh93 --version                                                                                                                                                               
  version         sh (AT&T Research) 93t+ 2010-02-02
# ./test_int_limit.ksh93 
INT_MAX-1 = 2147483646
INT_MAX   = 2147483647
INT_MAX+1 = 2147483648

ULONG_MAX-1 = 4294967294
ULONG_MAX   = 4294967295
ULONG_MAX+1 = 4294967296

i = 999999999999999998
i+1 = 999999999999999999
i+2 = 1e+18

LLONG_MAX-1 = 9223372036854775806
LLONG_MAX   = 9.22337203685477581e+18
LLONG_MAX+1 = 9.22337203685477581e+18
このように、18桁までは整数、19桁以上は浮動小数点数として扱ってくれるようです。
そうです。ksh は浮動小数点数を扱えます。一方、bash では浮動小数点数を扱えません。
ごく稀に、bash でも浮動小数点数を使いたい場合があり、やむなく gawk を呼び出したりしますが、ksh ならそのようなことをしなくても済むようです。
なお、ksh の typeset には、-i オプション (整数型指定) がありますが、これを指定すると内部的に int 扱いになるようで、INT_MAX までしか格納できなくなります。

bash と tcsh の扱える整数の上限については、次の記事参照。
bash で扱える整数の上限
tcsh で扱える整数の上限

tcsh で扱える整数の上限

以前、bash で扱える整数の上限 という記事を書きましたが、tcsh についても調べてみました。
#!/bin/tcsh

@ i=2147483646
echo "INT_MAX-1 = "$i
@ i++
echo "INT_MAX   = "$i
@ i++
echo "INT_MAX+1 = "$i
echo ""
@ i=4294967294
echo "ULONG_MAX-1 = "$i
@ i++
echo "ULONG_MAX   = "$i
@ i++
echo "ULONG_MAX+1 = "$i
echo ""
@ i=9223372036854775806
echo "LLONG_MAX-1 = "$i
@ i++
echo "LLONG_MAX   = "$i
@ i++
echo "LLONG_MAX+1 = "$i
echo ""
実行結果は次の通りです。
# tcsh --version                                                                                                                                                                
tcsh 6.17.00 (Astron) 2009-07-10 (x86_64-unknown-linux) options wide,nls,dl,al,kan,rh,color,filec
# ./test_int_limit.tcsh                                                                                                                                                         
INT_MAX-1 = 2147483646
INT_MAX   = 2147483647
INT_MAX+1 = -2147483648

ULONG_MAX-1 = -2
ULONG_MAX   = -1
ULONG_MAX+1 = 0

LLONG_MAX-1 = -2
LLONG_MAX   = -1
LLONG_MAX+1 = 0
このように、現在の tcsh では INT_MAX までしか扱え無いようです (注:実験は、64bit環境で行ってます) 。もし、仕事で csh を指定されているなど、どうしても csh 系でスクリプトを書くという方は、お気をつけて。
なお、あちこちで言われているように、csh 系でスクリプトを書くのはやめたほうが良いだろうと思います。最大の難点は、関数定義できない点だと思います。

参考URL:
有害な csh プログラミング
結論: csh はプログラミングにはまったく向かないツールであり、
そのような目的に使うことは厳しく禁じられるべきである!
8. まとめ ... そもそもが欠陥品なのです。
人気ブログランキングへ にほんブログ村 IT技術ブログへ