MinGW

MinGWは、フリーで入手できるGNUのCコンパイラ(gcc)のWindows版です。
市販のコンパイラを使わなくても、MinGWでTcl/Tkの実行形式を作成したり、
C言語でTcl/Tkの拡張パッケージを作成できます。

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

MinGWはDOS上から使うことができますが、MSYSとCygwinから使った方が便利です。
ここでは、MSYSCygwinからMinGWを使う方法を簡単に説明します。

MSYS & MinGW

最初は、MSYSからMinGWを使う方法です。
MSYSは、MinGW環境でconfigureを動かすための環境です。
Cygwinに比べてインストールが簡単です。

まず、MSYS-1.0.8-i686-2002.05.13-1.exeを実行してMSYSをインストールします。
インストールする場所は、とりあえず、デフォルトの C:/msys/1.0 にします。
インストール中にMinGWのある場所を聞かれますが、ない場合は、n を入力します。
あとは、適当にEnterキーを数回打てばインストールは完了します。
次に、MinGWをインストールします。
MSYSを起動します。MSYSのコンソール・ウィンドウが開くので、
以下のコマンドを入力して、MinGWをインストールします。

$ cd /mingw
$ tar xvzf MinGW-1.1.tar.gz

これでMSYSとMinGWのインストールは完了です。

Cygwin & MinGW

一方、Cygwinの環境でもMinGWを使えます。
インストールはsetup.exeで行うのですが、長くなるので割愛します。(^^;)
Cygwinの最新版1.3.10は、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をビルドする

Tcl/Tk 8.3.4のソースコードをビルドするには、以下のように行います。
Cygwinの場合は、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

さらに、gcc 3.1から以下のCPUタイプが追加されています。

CPUタイプ説明
pentium2PentiumII/Celeron(Covington, Mendocino)
pentium3PentiumIII/Celeron(Coppermine, Tualatin)
pentium4Pentium4/Celeron(Willamette, Northwood)
athlon-tbirdAthlon(Thunderbird)
athlon-4Athlon4
athlon-xpAthlon XP
athlon-mpAthlon MP

その他に、gcc 3.1からSSE命令を使って浮動小数点演算を行う-mfpmath=sseオプションも追加されています。

ベンチマークテスト

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.1では最適化機能が向上しているようです。

参考文献