ラベル コンパイラ の投稿を表示しています。 すべての投稿を表示
ラベル コンパイラ の投稿を表示しています。 すべての投稿を表示

2016-05-07

UnixBench - UNIX系OS向けベンチマーク (2)

UNIX 系 OS 向けベンチマークとして、以前、UnixBench を紹介しました [1]。今回は、C コンパイラの違いでベンチマークの結果が違ってくるかどうかを調べてみました。最初、候補に挙げたコンパイラは GCC, Clang, pcc の3つでしたが、コンパイル名を変えただけでは pcc のコンパイルが出来なかったので、GCC と Clang の比較にとどめました。

ベンチマークのターゲットにした環境は前回と同じく下記のとおりです。

GCC

GCC, GNU Compiler Collection の gcc は Linux Kernel のデフォルトコンパイラです。Fedora 24 では、GCC の version 6 が採用されています。Fedora 24 Alpha 版に収録されている GCC のバージョンは 6.0.0 です。ちなみに 4 月 27 日に GCC 6.1 がリリースされていますので、Fedora 24 のリリースでは GCC 6.1 以降が収録されると予想されます [3]。

GCC による UnixBench の実行方法は以下のとおりです。

$ cd byte-unixbench-master/UnixBench
$ ls
Makefile  README  Run  USAGE  WRITING_TESTS  pgms  src  testdir
$ make clean
rm -f ./pgms/arithoh ./pgms/register ./pgms/short ./pgms/int ./pgms/long ./pgms/float ./pgms/double ./pgms/hanoi ./pgms/syscall ./pgms/context1 ./pgms/pipe ./pgms/spawn ./pgms/execl ./pgms/dhry2 ./pgms/dhry2reg  ./pgms/looper ./pgms/fstime ./pgms/whetstone-double  core *~ */*~
$ make
make distr
make[1]: ディレクトリ '/home/bitwalk/ダウンロード/byte-unixbench-master/UnixBench' に入ります
Checking distribution of files
./pgms  exists
./src  exists
./testdir  exists
make[1]: ディレクトリ '/home/bitwalk/ダウンロード/byte-unixbench-master/UnixBench' から出ます
make programs
make[1]: ディレクトリ '/home/bitwalk/ダウンロード/byte-unixbench-master/UnixBench' に入ります
gcc -o pgms/arithoh -Wall -pedantic -O3 -ffast-math -march=native -mtune=native -I ./src -DTIME -Darithoh src/arith.c 
gcc -o pgms/register -Wall -pedantic -O3 -ffast-math -march=native -mtune=native -I ./src -DTIME -Ddatum='register int' src/arith.c 
gcc -o pgms/short -Wall -pedantic -O3 -ffast-math -march=native -mtune=native -I ./src -DTIME -Ddatum=short src/arith.c 
...
(省略)
...
make[1]: ディレクトリ '/home/bitwalk/ダウンロード/byte-unixbench-master/UnixBench' から出ます
$ ./Run
...
(省略)
...

Clang

Clang は、プログラミング言語 C, C++, Objective-C, Objective-C++ 向けのコンパイラフロントエンドです。バックエンドとして LLVM を使用しています。Mac OS X および iOS ならびに FreeBSD において標準のコンパイラとして採用されています。もちろん、Fedora でも利用できます。今回使用した Clang のバージョンは 3.8.0 です。

Clang による UnixBench の実行方法は以下のとおりです。

$ make clean
rm -f ./pgms/arithoh ./pgms/register ./pgms/short ./pgms/int ./pgms/long ./pgms/float ./pgms/double ./pgms/hanoi ./pgms/syscall ./pgms/context1 ./pgms/pipe ./pgms/spawn ./pgms/execl ./pgms/dhry2 ./pgms/dhry2reg  ./pgms/looper ./pgms/fstime ./pgms/whetstone-double  core *~ */*~
$ make CC=clang
make distr
make[1]: ディレクトリ '/home/bitwalk/ダウンロード/byte-unixbench-master/UnixBench' に入ります
Checking distribution of files
./pgms  exists
./src  exists
./testdir  exists
./tmp  exists
./results  exists
make[1]: ディレクトリ '/home/bitwalk/ダウンロード/byte-unixbench-master/UnixBench' から出ます
make programs
make[1]: ディレクトリ '/home/bitwalk/ダウンロード/byte-unixbench-master/UnixBench' に入ります
clang -o pgms/arithoh -Wall -pedantic -O3 -ffast-math -march=native -mtune=native -I ./src -DTIME -Darithoh src/arith.c 
clang -o pgms/register -Wall -pedantic -O3 -ffast-math -march=native -mtune=native -I ./src -DTIME -Ddatum='register int' src/arith.c 
clang -o pgms/short -Wall -pedantic -O3 -ffast-math -march=native -mtune=native -I ./src -DTIME -Ddatum=short src/arith.c 
...
(省略)
...
make[1]: ディレクトリ '/home/bitwalk/ダウンロード/byte-unixbench-master/UnixBench' から出ます
$ ./Run
...
(省略)
...

ベンチマーク結果

ベンチマーク結果の内、'2 CPUs in system; running 2 parallel copies of tests' の部分を以下にまとめました。

========================================================================
   BYTE UNIX Benchmarks (Version 5.1.3)

   System: stream11: GNU/Linux
   OS: GNU/Linux -- 4.5.2-302.fc24.x86_64 -- #1 SMP Wed Apr 27 14:22:29 UTC 2016
   Machine: x86_64 (x86_64)
   Language: en_US.utf8 (charmap="UTF-8", collate="UTF-8")
   CPU 0: Intel(R) Celeron(R) CPU N2840 @ 2.16GHz (4326.4 bogomips)
          Hyper-Threading, x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET, Intel virtualization
   CPU 1: Intel(R) Celeron(R) CPU N2840 @ 2.16GHz (4326.4 bogomips)
          Hyper-Threading, x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET, Intel virtualization
Compiler gcc-6.0.0 clang-3.8.0
System Benchmarks Index Values INDEX INDEX
Dhrystone 2 using register variables 2,204.2 2,092.7
Double-Precision Whetstone 787.4 777.0
Execl Throughput 732.5 737.5
File Copy 1024 bufsize 2000 maxblocks 973.1 998.3
File Copy 256 bufsize 500 maxblocks 686.2 686.4
File Copy 4096 bufsize 8000 maxblocks 1,562.1 1,644.8
Pipe Throughput 1,417.8 1,408.7
Pipe-based Context Switching 457.5 453.9
Process Creation 873.6 886.1
Shell Scripts (1 concurrent) 886.5 901.3
Shell Scripts (8 concurrent) 844.6 838.4
System Call Overhead 1,822.0 1,850.0
System Benchmarks Index Score 1,002.1 1,005.7

ベンチマークの結果は、意外にも Clang のスコアの方がやや上回っていました。Clang/LLVM が、コンパイラに求められる現代的な機能を実現しているとは言え、コンパイルしたバイナリの実行速度では、まだ GCC のレベルには達していないと思っていたからです。

しかし、前回 UnixBench を紹介した時に、同じ環境および GCC で実施したスコアが、今回よりやや高い 1016.6 であったことを考えると、スコアの差はばらつきの範囲と考えて差し支えなさそうです [1]。このベンチマーク方法でコンパイラの性能差を精度よく評価できるかは判らないものの、GCC と Clang の差は、このベンチマークテストでは認められなかったということになります。

コンパイラ評価用のプログラムは、他のサイトで紹介されていますので、機会をみて試してみようと思います [4]。

参考サイト

  1. bitWalk's: UnixBench - UNIX系OS向けベンチマーク
  2. kdlucas/byte-unixbench: Automatically exported from code.google.com/p/byte-unixbench
  3. GCC Development Plan - GNU Project - Free Software Foundation (FSF) Version Numbering Scheme for GCC 5 and Up
  4. コンパイラ評価用プログラム

 

ブログランキング・にほんブログ村へ
にほんブログ村

2010-12-04

LLVM に関する話題 2010

LLVM のホットな情報にタイムリーには喰いつけず、ぼんやりしていた自分に悔しかったので、ここで今年一年分の情報をまとめてみたいと思います。
[01] 2010/02/09 あるコンパイラが重要なマイルストーンに到達
[02] 2010/04/19 FreeBSD Daily Topics:2010年4月19日 FreeBSD GCCを置き換えるLLVM Clang,広くテスト呼びかけ
[03] 2010/04/28 LLVM 2.7登場、飛竜を公式ロゴに採用
[04] 2010/04/29 LLVMプロジェクト、対応プラットフォームを強化した「LLVM 2.7」
[05] 2010/05/17 JITコンパイラにLLVMを使用するRuby互換実装「Rubinius 1.0」が登場
[06] 2010/05/18 LLVM、GCC libstdc++をBSDライセンスのlibc++へ置き換え
[07] 2010/05/18 LLVM 2.7、Haskell対応のストーリー
[08] 2010/05/25 【レポート】FreeBSD GCCアップデート停止、LLVM Clangへ移行 - BSDCan 2010
[09] 2010/06/10 FreeBSD Daily Topics:2010年6月10日 LLVM Clang,FreeBSD 9-CURRENTへ統合
[10] 2010/06/11 LLVM Project、次世代デバッガ「LLDB」を開発へ
[11] 2010/10/08 LLVM 2.8登場、C++大幅強化
[12] 2010/10/28 LLVM Clang、Linuxカーネルビルドに成功
[13] 2010/11/19 FreeBSD Daily Topics:2010年11月19日 LLVM Clang 2.8,9-CURRENTにマージ

ところで、Tcl と LLVM を結びつけるようなプロジェクトがないか探して見たところ、llvmtcl という、いわゆる拡張パッケージを開発するプロジェクトがありました。llvmtcl を評価ができたらレポートしたいと思います。

[14] jdc8/llvmtcl - GitHub

2010-05-03

LLVM 2.7 のベンチマーク (2)

LLVM のベンチマークと言っても、コンパイルに使用するライブラリのほとんどが GCC でビルドされたものであることを考えると、前回の Tcl を使ったベンチマークは、あまりにもアバウトな比較だったように思います。
 
そこで、今回は、GMP を利用した円周率の計算プログラムで、GCC と LLVM/clang のパフォーマンスを較べてみました。計算の主要部分である GMP ライブラリを GCC と clang でビルドして用いれば、もう少し精度の良い比較が出きると考えたからです。
 
GMP は最新の 5.0.1 のスタティックライブラリを GCC, LLVM/clang それぞれでビルドしてローカルアカウントの領域にインストール、そのライブラリを使い、円周率計算プログラムを、それぞれに対応するコンパイラでビルドして比較してみました。
 
円周率の計算プログラムのソースは、GNU/Linux上で円周率の計算をおこなうで紹介されている pi.c を利用させていただきました。
 
GMP をビルドするのに使用したスクリプト build-gmp.sh を以下に示しました。このスクリプトは作業エリア $HOME/work/Pi/GMP/ 内に GMP のソースがあり、インストール先が使用したコンパイラに応じて、$HOME/work/Pi/GMP/${CC} であることを想定しています。

#!/bin/sh
 
# C compiler
#export CC=gcc
export CC=clang
 
# constants
export ver="5.0.1"
 
# remove old sources
echo "### Removing old sources & binaries"
rm -fR gmp-${ver}
 
# extract sources
echo "### Expanding sources to build"
tar jxvf gmp-${ver}.tar.bz2
 
# build GMP
echo "### build GMP"
cd gmp-${ver}
./configure --prefix=$HOME/work/Pi/GMP/${CC} \
--disable-shared --enable-static
make
make install

GCC と LLVM/clang でそれぞれビルド、円周率を計算した結果を以下に示しました。使用した PC は Thinkpad X31 です。なお、あらかじめ glibc のスタティックライブラリの RPM glibc-static がインストールされている必要があります。

### GCC 4.4.3
 
$ time ./build-gmp.sh
real 3m28.100s
user 0m50.568s
sys 1m19.172s
 
$ ls -l ./gcc/lib/libgmp.a
-rw-r--r--. 1 bitwalk bitwalk 816078 2010-05-03 23:24 ./gcc/lib/libgmp.a
 
$ gcc -static -O2 -I./gcc/include pi.c ./gcc/lib/libgmp.a -o pi
$ time ./pi > pi.dat
real 0m19.522s
user 0m18.564s
sys 0m0.661s
 
 
### LLVM/clang 2.7
 
$ time ./build-gmp.sh
real 4m2.098s
user 1m11.869s
sys 1m30.534s
 
$ ls -l ./clang/lib/libgmp.a
-rw-r--r--. 1 bitwalk bitwalk 739022 2010-05-03 23:36 ./clang/lib/libgmp.a
 
$ clang -static -O2 -I./clang/include pi.c ./clang/lib/libgmp.a -o pi
$ time ./pi > pi.dat
real 0m19.584s
user 0m18.661s
sys 0m0.622s

今回は、GMP のビルドに要した時間も計測してみましたが、意外にも clang でビルドした場合の方が時間が掛かっています(+16.3% 程度)。バイナリ libgmp.a のサイズは clang でビルドした方が明らかに小さく(-9.4% 程度)、実行速度は GCC よりやや遅い(+0.3% 程度)という結果になりました。
 
余談になりますが、Fedora 13(β版)の RPM パッケージ GMP 4.3.1 のスタティックライブラリを使って普通にビルドした場合の計算時間も確認しました。GMP 5.0.1 との差にびっくりです。

$ gcc -static -O2 pi.c -lgmp -o pi
$ time ./pi > pi.dat
real 0m38.492s
user 0m37.361s
sys 0m0.605s

参考サイト


[1] GNU/Linux上で円周率の計算をおこなう
[2] The GNU MP Bignum Library
 

2010-05-02

LLVM 2.7 のベンチマーク

先日リリースされたばかりの LLVM 2.7 のベンチマークを、前回と同様に取ってみました。OS / マシン は、Fedora 13(β版)/ 32bit の古いノート PC (ThinkPad X31) を使用しています。

LLVM/clang の RPM は、rawhide のパッケージ llvm-2.7-0.1.pre1.fc14.src.rpm の spec ファイルを書き換え、LLVM と clang のソースファイルも 2.7 リリース版に置き換えてビルドしたパッケージを使用しました。

ベンチマークに使用した Tcl は、nightly-cvs 版 tcl-20100430.tar.gz です。 以下に GCC 4.4.3 と LLVM/clang-2.7 のベンチマーク結果を示しました。

Fedora 13 (32bit i686)
tcl-20100430
# GCC 4.4.3
1000000 repeats in 0.146364
10000 iterative factorial(100) in 74.794581
10000 iterative factorial(100) with 'if' in 75.131586
10000 recursive factorial(100) in 90.248124
1000 exec calls in 5.680614
total time was 246.00126899999998
 
# LLVM/clang 2.7
1000000 repeats in 0.170331
10000 iterative factorial(100) in 77.283847
10000 iterative factorial(100) with 'if' in 77.356544
10000 recursive factorial(100) in 93.987031
1000 exec calls in 5.631689
total time was 254.429442

依然として clang で生成したバイナリの方が遅いのですが、その差は 3 - 4% 程度でした。

clang-2.7 では C++ のセルフホスティングに対応し、LLVM と clang のビルドが可能になったということです。次の興味としては、clang でビルドした LLVM/clang のパフォーマンスがどうなのかなのですが、まずは clang でビルド出来ることを確認してみます。
 

2010-04-29

【備忘録】LLVM の IR って?

LLVM を使い始めてまだ日が浅いので、マニュアルを読むと解らない用語がいろいろあります。

頻繁に出てくる LLVM IR あるいは an in-memory compiler IR という表現で使われている IR もその一つです。

どうやら IR は Instruction Register の略語だと思うのですが…、ちょっと自信がありません。とりあえず【備忘録】として残しておきます。

【訂正】 02-May-2010
[2] の記事に書いてありました。IR とは Intermediate Representation の略でした。

関連サイト


[1] Bootstrapping (computing) - Wikipedia, the free encyclopedia
[2] LLVMプロジェクト、対応プラットフォームを強化した「LLVM 2.7」
 

2010-04-17

LLVM と clang

以前から気になっていた LLVM と clang を、Fedora 12 上で使ってみました。

LLVM は Low Level Virtual Machine の略で、プログラミング言語に対する仮想マシン(コンパイラ・インフラストラクチャ)です。この仮想マシンには RISC CPU のようなインストラクションセット(マシン語)が構成されています。プログラミング言語で記述されたプログラムを、LLVM のフロントエンドのコンパイラが仮想マシン LLVM のマシン語に翻訳し、LLVM が言語やプラットフォームから独立して最適化を行い、ターゲット CPU のマシン語を生成します。

clang(クラング)は、C 系のプログラミング言語 (C, C++, Objective C/C++) をサポートする LLVM のフロントエンド(コンパイラ)で、GCC と互換性があります。また、プログラムを開発する IDE とインターフェースを取りやすいように考慮された設計になっています。

SYNOPSIS
clang [-c|-S|-E] -std=standard -g
[-O0|-O1|-O2|-Os|-O3|-O4]
-Wwarnings... -pedantic
-Idir... -Ldir...
-Dmacro[=defn]
-ffeature-option...
-mmachine-option...
-o output-file
input-filenames

どちらのライセンスも、BSD ライセンスをベースにした University of Illinois/NCSA Open Source License です。

さて、Fedora 12 で LLVM と clang 関連 RPM を利用するには、yum で次のようにしてインストールします。

$ yum install llvm* clang*

LLVM、clang のバージョンは 2.6 で、最新の安定版です。

clang で生成したバイナリが、どの程度のパフォーマンスを持っているのか気になるので、Tcl の nightly-CVS(Tcl8.6b1.1, tcl-20100415.tar.gz) ファイルをダウンロードして、gcc と clang それぞれでコンパイルしたバイナリのベンチマークを取ってみました。

Tcl のビルドに使用したスクリプトを以下に示します。

#!/bin/sh
 
# C compiler
#export CC=gcc
export CC=clang
 
# constants
export cvs_ver="20100415"
 
# remove old sources
echo "### Removing old sources & binaries"
rm -fR tcl
 
# extract sources
echo "### Expanding sources to build"
tar zxvf tcl-${cvs_ver}.tar.gz
 
# build Tcl
echo "### build Tcl"
cd tcl/unix
./configure --prefix=$HOME
make
make test
make install

clang でビルドした際に、警告メッセージが gcc の時と違って、ずいぶんと親切な内容であったことが印象的でした。例を以下に示します。

clang -c -DNDEBUG -O2 -pipe -fvisibility=hidden -Wall -fPIC -DBUILD_tcl -I"."
-I/home/bitwalk/src/tcl/unix -I/home/bitwalk/src/tcl/generic -I/home/bitwalk/src
/tcl/libtommath -DPACKAGE_NAME=\"tcl\" -DPACKAGE_TARNAME=\"tcl\" -DPACKAGE_VERSI
ON=\"8.6\" -DPACKAGE_STRING=\"tcl\ 8.6\" -DPACKAGE_BUGREPORT=\"\" -DSTDC_HEADERS
=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1
-DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAV
E_UNISTD_H=1 -DHAVE_LIMITS_H=1 -DHAVE_SYS_PARAM_H=1 -DUSE_THREAD_ALLOC=1 -D_REEN
TRANT=1 -D_THREAD_SAFE=1 -DTCL_THREADS=1 -DTCL_CFGVAL_ENCODING=\"iso8859-1\" -DH
AVE_ZLIB=1 -DTCL_SHLIB_EXT=\".so\" -DTCL_CFG_OPTIMIZED=1 -DTCL_CFG_DEBUG=1 -DTCL
_TOMMATH=1 -DMP_PREC=4 -D_LARGEFILE64_SOURCE=1 -DTCL_WIDE_INT_TYPE=long\ long -D
HAVE_STRUCT_STAT64=1 -DHAVE_OPEN64=1 -DHAVE_LSEEK64=1 -DHAVE_TYPE_OFF64_T=1 -DHA
VE_GETCWD=1 -DHAVE_MKSTEMP=1 -DHAVE_OPENDIR=1 -DHAVE_STRTOL=1 -DHAVE_WAITPID=1 -
DHAVE_GETADDRINFO=1 -DHAVE_GETPWUID_R_5=1 -DHAVE_GETPWUID_R=1 -DHAVE_GETPWNAM_R_
5=1 -DHAVE_GETPWNAM_R=1 -DHAVE_GETGRGID_R_5=1 -DHAVE_GETGRGID_R=1 -DHAVE_GETGRNA
M_R_5=1 -DHAVE_GETGRNAM_R=1 -DHAVE_GETHOSTBYNAME_R_6=1 -DHAVE_GETHOSTBYNAME_R=1
-DHAVE_GETHOSTBYADDR_R_8=1 -DHAVE_GETHOSTBYADDR_R=1 -DUSE_TERMIOS=1 -DHAVE_SYS_T
IME_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_GMTIME_R=1 -DHAVE_LOCALTIME_R=1 -DHAVE_MKT
IME=1 -DHAVE_TM_GMTOFF=1 -DHAVE_TIMEZONE_VAR=1 -DHAVE_STRUCT_STAT_ST_BLOCKS=1 -D
HAVE_STRUCT_STAT_ST_BLKSIZE=1 -DHAVE_BLKCNT_T=1 -DHAVE_INTPTR_T=1 -DHAVE_UINTPTR
_T=1 -DHAVE_SIGNED_CHAR=1 -DHAVE_LANGINFO=1 -DHAVE_MKSTEMPS=1 -DHAVE_FTS=1 -DHAV
E_SYS_IOCTL_H=1 -DTCL_UNLOAD_DLLS=1 /home/bitwalk/src/tcl/generic/tclBasic
.c
/home/bitwalk/src/tcl/generic/tclBasic.c:7652:2: warning: expression result unus
ed [-Wunused-value]
TclGetLongFromObj(NULL, objPtr, &iResult);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/bitwalk/src/tcl/generic/tclInt.h:2460:57: note: instantiated from:
? ((*(longPtr) = (objPtr)->internalRep.longValue), TCL_OK) \
^
/home/bitwalk/src/tcl/generic/tcl.h:635:18: note: instantiated from:
#define TCL_OK 0
^
/home/bitwalk/src/tcl/generic/tclBasic.c:7892:2: warning: expression result unus
ed [-Wunused-value]
TclGetLongFromObj(NULL, objPtr, &i);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/bitwalk/src/tcl/generic/tclInt.h:2460:57: note: instantiated from:
? ((*(longPtr) = (objPtr)->internalRep.longValue), TCL_OK) \
^
/home/bitwalk/src/tcl/generic/tcl.h:635:18: note: instantiated from:
#define TCL_OK 0
^
/home/bitwalk/src/tcl/generic/tclBasic.c:8897:5: warning: expression result unus
ed [-Wunused-value]
TclGetString(cmdObjPtr);
^~~~~~~~~~~~~~~~~~~~~~~
/home/bitwalk/src/tcl/generic/tclInt.h:3957:33: note: instantiated from:
((objPtr)->bytes? (objPtr)->bytes : Tcl_GetString((objPtr)))
~~~~~~~~ ^~~~~
3 diagnostics generated.

Tcl のベンチマークは、Tcl benchmark tests のサイトのスクリプトの一部を使用しました。32bit の x86 版 Fedora 12 上で、gcc と clang それぞれのベンチマークを取った結果は以下のようになりました。数値の単位は「秒」です。

### gcc
$ ls -l libtcl8.6.so
-r-xr-xr-x. 1 bitwalk bitwalk 1393392 2010-04-17 09:15 libtcl8.6.so

$ tclsh8.6 benchmark.tcl
1000000 repeats in 0.169659
10000 iterative factorial(100) in 73.867148
10000 iterative factorial(100) with 'if' in 73.777363
10000 recursive factorial(100) in 88.282079
1000 exec calls in 1.600121
total time was 237.69637
 
### LLVN & clang
$ ls -l libtcl8.6.so
-r-xr-xr-x. 1 bitwalk bitwalk 1371875 2010-04-17 09:54 libtcl8.6.so
 
$ tclsh8.6 benchmark.tcl
1000000 repeats in 0.165494
10000 iterative factorial(100) in 79.013924
10000 iterative factorial(100) with 'if' in 79.165719
10000 recursive factorial(100) in 95.940107
1000 exec calls in 1.549376
total time was 255.83461999999997

64bit 版 Fedora 12 上でも、--enable-64bit スイッチを加えてビルドした Tcl を試しましたが、現時点では、どちらの場合も、clang でビルドしたバイナリによる計算速度は、gcc でビルドしたものより 5 - 10 % 程度遅いという結果になりました。バイナリのサイズは clang で生成した方が、やや小さくなっています。

IDE でプログラムを開発する場合のメリットを調べる必要があります。機会があれば紹介しようと思います。

参考サイト


[1] The LLVM Compiler Infrastructure Project
[2] LLVM 2.6リリース - SourceForge.JP Magazine : オープンソースの話題満載
[3] LLVMのコンパイラ「Clang」、セルフホスティングに成功 - SourceForge.JP Magazine : オープンソースの話題満載
 

2008-02-19

Visual Studio 2008 Express Editions

インターネットである情報を探していたら、ひょんなことから Visual Studio 2008 Express Editions のサイトにたどり着き、これは使えそうだと思い、早速オンライン・インストールをしました。

ずっと昔、Visual C++ 6 までは購入して使っていましたが、コンパイラの用途が購入価格に見合わず、結局 Cygwin/MinGW の GCC を利用するようになってしまいました。

Visual Studio 2008 Express Editions の「よくある質問」によると、30日以上使い続けるにはユーザー登録をしなければならないものの、Visual Studio Express Edition を使用して作成したアプリケーションについては、ライセンスの制限がないということです。また、Visual C++ 2008 Express Edition には、MFC と ATL が含まれていないが、基本的な Optimizing Compiler が含まれているとのことなので、Tcl/Tk などのコンパイルには使えそうです。


そこで、Tcl/Tk 8.5.1 をコンパイルしてみました。
まず、SourceForge.net のサイトから Tcl/Tk8.5.1 のソース(tcl8.5.1-src.tar.gz と tk8.5.1-src.tar.gz、あるいは zip ファイル)をダウンロードしてきて圧縮ファイルを解凍(展開)しておきます。ここでは、E:\mingw\src\ 以下にソースを展開しています。

次に、スタートメニューから、Visual Studio 2008 コマンドプロンプトを起動します。

最初に、Tcl からコンパイルします。インストール先のトップディレクトリを、環境変数 INSTALLDIR にセットしてからビルドします。

Setting environment for using Microsoft Visual Studio 2008 x86 tools.

C:\Program Files\Microsoft Visual Studio 9.0\VC>e:

E:\>cd mingw\src

E:\mingw\src>set INSTALLDIR=e:\mingw\build\Tcl

E:\mingw\src>cd tcl8.5.1\win

E:\mingw\src\tcl8.5.1\win>nmake -fmakefile.vc

Microsoft(R) Program Maintenance Utility Version 9.00.21022.08
Copyright (C) Microsoft Corporation. All rights reserved.

===============================================================================
*** Compiler has 'Optimizations'
*** Compiler does not have 'Pentium 0x0f fix'
:
:
:
LINK : warning LNK4224: /OPT:NOWIN98 はサポートされていません。無視されます。
ライブラリ .\Release_VC9\tcldde13.lib とオブジェクト .\Release_VC9\tcldde13.e
xp を作成中
コード生成しています。
コード生成が終了しました。
if exist .\Release_VC9\tcldde13.dll.manifest mt -nologo -manifest .\Rele
ase_VC9\tcldde13.dll.manifest -outputresource:.\Release_VC9\tcldde13.dll;2

E:\mingw\src\tcl8.5.1\win>nmake -fmakefile.vc install

Microsoft(R) Program Maintenance Utility Version 9.00.21022.08
Copyright (C) Microsoft Corporation. All rights reserved.

===============================================================================
*** Compiler has 'Optimizations'
*** Compiler does not have 'Pentium 0x0f fix'
:
:
:
Installing package platform::shell 1.1.3 as a Tcl Module
Installing tcldde13.dll
Installing tclreg12.dll
Installing encodings

E:\mingw\src\tcl8.5.1\win>

次に、Tk をビルドします。ビルドの前に、環境変数 TCLDIR へ tcl8.5.1 のソースのトップディレクトリをセットします。インストール先は、この場合は Tcl と同じにしました。つまり、環境変数 INSTALLDIR の値はそのままです。

E:\mingw\src\tcl8.5.1\win>cd ..\..\tk8.5.1\win

E:\mingw\src\tk8.5.1\win>set TCLDIR=e:\mingw\src\tcl8.5.1

E:\mingw\src\tk8.5.1\win>nmake -fmakefile.vc

E:\mingw\src\tk8.5.1\win>nmake -fmakefile.vc install

以上が Tcl/Tk の基本的なビルド手順です。ちなみに、nmake /f と nmake -f の両方の形式が可能です。つい癖で -f と入力してしまうのですが、エラーが出なかったので気が付きました。

生成したバイナリについての詳細な評価はまだしていませんが、とりあえず、MinGW クロスコンパイラでビルドした Tcl/Tk のバイナリと、ファイルサイズを比較してみました。

Visual C++ でビルドしたバイナリ



MinGW クロスコンパイラ でビルドしたバイナリ


明らかに、Visual C++ でビルドしたバイナリのサイズの方が小さいことが判ります。詳細なベンチマークを今後やってみたいと考えています。
昔、VC6 と MinGW の gcc で比較したときには、VC6 でコンパイラでビルドしたバイナリの方が、バイナリサイズが小さく、かつ実行速度も速いという結果が出たと記憶していますが、最新の gcc との比較で、どの程度の差が出るか興味があります。