Tcl/Tk Programming Kit for Windows & MinGW

2001年12月4日、bitWalkからTcl/Tk Programming Kit for Windows & MinGW Version 0.9.0が発売になりました。
MinGWというのは、GNUのCコンパイラ(gcc)のWindows版で、MinGWプロジェクトからフリーで入手できます。
MinGWを使うと、市販のMS Visual C++を使わずに、Tcl/Tkのソースコードから実行形式を ビルドしたり、
Tcl/Tkの拡張パッケージをC言語で作成できます。

Tcl MinGWキット

本Kitの製品構成は以下の通りです。

MinGW-1.1の構成は以下の通りです。

本Kitは、MS-DOSプロンプト(コマンドプロンプト)のみで、C言語で記述されたTcl/Tkの拡張パッケージを
コンパイルできることを目的にしています。
そのため、MinGWは、Inno Setupでコンパイルされたインストーラ形式になっています。
一方、Cygwinの環境でもMinGWを使えますが、Cygwinでのコンパイルについては言及していません。
通常、MinGWの配布物は、GNU TAR形式(.tar.gz)で配布されるので、Cygwinの方がなにかと便利だと思います。

Cygwin & MinGW

そこで、Cygwinユーザのために、CygwinからMinGWを使う方法を簡単に紹介します。
Cygwinの最新版1.3.6は、MinGW-1.1と1.2のCランタイムとw32apiを含んでいます。
GNU Cコンパイラ(gcc)のバージョンは、2.95.3-5です。
Cygwinでgccを使う場合、デフォルトでは、POSIXエミュレーションレイヤである
cygwin1.dll介した実行形式が生成されます。 Windowsネイティブな実行形式を生成するには、
gccに-mno-cygwinオプションを指定します。

Tcl/Tk 8.3.4のソースコードをビルドするには、以下のように行います。
configureが-mno-cygwinオプション付きのMakefileを生成してくれます。

$ cd tcl8.3.4/win
$ ./configure --enable-gcc --enable-threads
$ make

$ cd tk8.3.4/win
$ ./configure --enable-gcc --enable-threads
$ make

出来た実行形式がcygwin1.dllに依存していないかを調べるにはobjdumpコマンドを使います。

$ objdump -p tclsh83.exe | grep "\.dll"
	DLL Name: msvcrt.dll
	DLL Name: KERNEL32.dll
	DLL Name: tcl83.dll
	
$ objdump -p wish83.exe | grep "\.dll"
	DLL Name: msvcrt.dll
	DLL Name: KERNEL32.dll
	DLL Name: USER32.dll
	DLL Name: tcl83.dll
	DLL Name: tk83.dll

cygwin1.dllの代わりにmsvcrt.dllが表示されれば、問題ないでしょう。
ちなみに、msvcrt.dllは、MS社のCランタイムで、Windowsに標準で備わっています。

gccの最適化オプション

一般に、gccの最適化機能は、市販のコンパイラより劣ると言われています。
gccの最適化オプションは以下のようになっています。(gcc version 2.95.3-5)
その他のオプションについては、最適化を制御するオプションを参照してください。

オプション説明
-O-O1と同じ
-O0最適化を行わない
-O1コードサイズ削減と実行速度向上を目指す最適化を行う
変数をレジスタに割り当てたり、多重条件ジャンプの最適化などを行う
-O2さらに高度な最適化を実行する。ほとんどの最適化機能が有効になが、
ループ展開と関数のインライン展開、レジスタのリネームは行わない
-O3-O2より進んだ最適化を行う。ループ展開や関数のインライン展開なども行う
-Osコードサイズを小さくするための最適化を行う。-O0〜3などの実行速度を向上させるオプションとも併用できます
※ Pentium以降のプロセッサに特化したpgccのように、-O7まで指定可能なコンパイラもあります。

通常、コンパイラのバグなどに遭遇する恐れがあるので、-O2を使うのが無難です。

CPUに特化した最適化

gccには、CPUに応じた最適化を指示するオプション-marchと-mcpuもあります。
-marchは、指定したCPUだけで動作するようなコードを出力します。
-mcpuは、同系列のCPUでも動作するようなコードを出力します。
実行速度は、-marchの方が速くなります。
それぞれ、-march=i686、-mcpu=pentiumproのように使います。
指定できるCPUタイプは共通で以下の通りです。

CPUタイプ説明
i386i386やその互換CPU
i486i486やその互換CPU
i586Pentium, MMX Pentium,やその互換CPU
i686Pentium Pro, Pentium II, Pentium III, Pentium 4, Celeronなど
pentiumi586と同じ
pentiumproi686と同じ
k6K6, K6-2, K6-III
athlonAthlon, Athlon MP, Athlon XP

ベンチマークテスト

MS社のVisual C++でビルドされたActiveTcl 8.3.4.1とMinGW-1.1でビルドされたTcl8.3.4のベンチマークテストを行いました。
まずは、自作のTkEngine V1.0でテストしました。
結果は予想に反して、MinGWビルド版の方が若干速いという結果になりました。

環境TkEngine値
ActiveTcl 8.3.4.131
Tcl8.3.4 MinGWビルド版33

次に、須栗歩人さんが、1997年11月に公開されたTcl/Tk Benchmark Ver.1.3を使ってテストしました。
この結果も、MinGWビルド版の方が若干速いという結果になりました。誤差の範囲かもしれません。

環境項目実行時間
ActiveTcl 8.3.4.1LINE0.98秒
PAINT0.89秒
MOVE1.77秒
TOTAL3.64秒
Tcl8.3.4 MinGWビルド版LINE0.93秒
PAINT0.85秒
MOVE1.69秒
TOTAL3.47秒

最後に、MetaCardのPerformance Benchmarks を使ってテストしました。
この結果は、MinGWビルド版の方が若干遅いという結果になりました。誤差の範囲かもしれません。

環境項目実行時間
ActiveTcl 8.3.4.11000000 repeats1.162秒
10000 iterative factorial(100)49.942秒
10000 iterative factorial(100) with 'if'50.382秒
10000 recursive factorial(100)87.316秒
1000 exec calls16.183秒
2000 100-line file writes and reads6.199秒
10 stem generation took5.017秒
total time was216.201秒
Tcl8.3.4 MinGWビルド版1000000 repeats1.122秒
10000 iterative factorial(100)50.803秒
10000 iterative factorial(100) with 'if'51.354秒
10000 recursive factorial(100)88.858秒
1000 exec calls16.864秒
2000 100-line file writes and reads5.398秒
10 stem generation took5.658秒
total time was220.057秒

これだけのデータでは、なんとも言えませんが、このテストの結果では、
ActiveTclとMinGWビルド版は互角の性能で、十分に実用的であると言えます。
さらに、gcc 3.0でどのくらい最適化機能が向上しているか期待してしまう。

最後に

本MinGW Kitは、本Kitの目的に合っている方であれば、十分に価値のある導入Kitであると思います。
付録のCD-Rに収録されているものは、ほとんどがインターネットを通して入手ができますが、
とりあえず、解説書狙いで購入してみてはいかがでしょうか?
私は、今後出るV1.0の解説書の内容充実、分冊化に期待しつつ、Borland C版Kitにも期待しています。

参考文献