魔術師見習いのノート

プロフィール

魔術師見習い
Author魔術師見習い-_-.
Twitter魔術師見習い

コンピュータ関係のメモを主に書きます.

MENU

SESCのコンパイル

投稿日:
タグ:

Debian6-0.2.1でSESCをコンパイルする際にうまくいかなかったのでその時の苦労をメモ.コードを書き換えたりしているが,とりあえず実行できるものはできた.

作業環境

コンパイルに用いた環境はこんな感じである.

archx86_64
OSDebian6-0.2.1
pwd/home/user/00_workspace/sesc
GCCのバージョン情報※後述のものを参照
user% gcc -v
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.5-8'
--with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs
--enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-4.4 --enable-shared --enable-multiarch
--enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib
--without-included-gettext --enable-threads=posix
--with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib
--enable-nls --enable-clocale=gnu --enable-libstdcxx-debug
--enable-objc-gc --with-arch-32=i586 --with-tune=generic
--enable-checking=release --build=x86_64-linux-gnu
--host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.4.5 (Debian 4.4.5-8) 

SESCの取得

SESCはの取得は, Hashim's Space を参考に行った.以下のコマンドを実行するとカレントディレクトリにsescディレクトリが生成される.

user% cvs -z3 -d:pserver:anonymous@sesc.cvs.sourceforge.net:/cvsroot/sesc co -P sesc 
コマンドの詳細については省略する.

コンパイル

流れとしては,"configure"によってシミュレータの種類を設定,"make"によってソースコードをコンパイルし,"make sesc.conf"でシミュレータの標準(オプションで指定しなかった場合のパラメータ)の設定ファイルを用意する."make sesc.conf"はconfsディレクトリからただコピーしてくるだけだが,シミュレータの種類に応じて適切なものをコピーしてくれる.

はじめにconfigureスクリプトを走らせる.今回は特にオプションを指定しない.

user% ./configure
configure: creating ./config.status
config.status: creating Makefile
config.status: creating Make.defs

次にMAKEコマンドを実行する.

user% make
g++  -O3 -momit-leaf-frame-pointer -march=i686 -funroll-loops
-fsched-interblock  -ffast-math -fno-strict-aliasing -freg-struct-return
-I/home/user/00_workspace/sesc/obj/Linux_obj
-I/home/user/00_workspace/sesc/./src/libapp
-I/home/user/00_workspace/sesc/./src/libsuc
-I/home/user/00_workspace/sesc/./src/libcore
-I/home/user/00_workspace/sesc/./src/libnet
-I/home/user/00_workspace/sesc/./src/libmem
-I/home/user/00_workspace/sesc/./src/libvmem
-I/home/user/00_workspace/sesc/./src/libll
-I/home/user/00_workspace/sesc/./src/libmint
-I/home/user/00_workspace/sesc/./src/libpint
-I/home/user/00_workspace/sesc/./src/libsmp -I.
-I/home/user/00_workspace/sesc/./src/librst -W -Wall
-Wno-unused -DPACKAGE_NAME=\"esesc\" -DPACKAGE_TARNAME=\"esesc\"
-DPACKAGE_VERSION=\"2\" -DPACKAGE_STRING=\"esesc\ 2\"
-DPACKAGE_BUGREPORT=\"renau@soe.ucsc.edu\ luisceze@cs.uiuc.edu\"
-DLINUX -DLENDIAN  -DSIMICS -DPOSIX_MEMALIGN -DNDEBUG -DDEBUG2=0 -o
/home/user/00_workspace/sesc/obj/Linux_obj/mkdep
/home/user/00_workspace/sesc/./src/misc/mkdep.cpp
/home/user/00_workspace/./src/misc/mkdep.cpp:1: error: CPU you selected
does not support x86-64 instruction set

開始して速攻で躓いた.

エラーの原因は選択したISAらしい.MAKEコマンドのログ情報を見てみると,コンパイラのクロスコンパイルなどをするための-marchオプションがi686になっているのが原因っぽい.GCCの設定ファイルってmake.confだったかなぁ(違うかも…)と思い探してみるが,見つからない.面倒臭いので他の方法が探してみた.

user% egrep i686 **/*
src/Makefile.defs.CYGWIN:COPTS  += -march=i686
src/Makefile.defs.Linux:# Default architecture is i686
src/Makefile.defs.Linux:OptArch := -march=i686
src/libsuc/Snippets.h:#if defined(__tune_i686__)
EGREPコマンドを使うと(GREPでも良いが),割と簡単にそれっぽいのを発見した.ファイルを見てみたところMakefile.defs.Linuxを書き換えれば良さそうである.ちなみに**/*はZSHが使用可能なパターンマッチングの方法である.VIコマンドで-march=より右をnoconaかcore2に変更する.
user% vi src/Makefile.defs.Linux 
Before:
     66 # Default architecture is i686
     67 OptArch := -march=i686
     68 # But now try to detect the real architecture
After:
     66 # Default architecture is i686
     67 #OptArch := -march=i686
     68 OptArch := -march=nocona
     69 # But now try to detect the real architecture
そして再びmakeコマンドを実行する.

──が,またしてもエラー.

/home/user/00_workspace/sesc/./src/libcore/FetchEngine.cpp:79:
error: ‘USHRT_MAX’ was not declared in this scope
FetchEngine.cppがlimits.hで定義されているUSHRT_MAXが読み込めてないらしい.面倒臭いので,読み込めてない原因は調べずコードを書き加えた.
Before:
     25 #include "SescConf.h"
     26 #include "FetchEngine.h"
     27 #include "OSSim.h"
     28 #include "LDSTBuffer.h"
     29 #include "GMemorySystem.h"
     30 #include "GMemoryOS.h"
     31 #include "GProcessor.h"
     32 #include "MemRequest.h"
     33 #include "Pipeline.h"
     34 
     35 
After:
     25 #include "SescConf.h"
     26 #include "FetchEngine.h"
     27 #include "OSSim.h"
     28 #include "LDSTBuffer.h"
     29 #include "GMemorySystem.h"
     30 #include "GMemoryOS.h"
     31 #include "GProcessor.h"
     32 #include "MemRequest.h"
     33 #include "Pipeline.h"
     34 
     35 #include <limits.h>
追加行は本来ならC++なので,#include <climits>とすべきかもしれないが,元々Cの書き方と混ざったソースコードだったので,気にせず<limits.h>とする.

FetchEngine.cppを解決すると,またしてもlimits.hが原因のエラー.

/home/user/00_workspace/sesc/./src/libcore/Cluster.cpp:161:
error: ‘INT_MAX’ was not declared in this scope
今度はCluster.cppでlimits.hで定義されたマクロがないと言われたので同じように追記する.
Before:
     23 #include "Cluster.h"
     24 
     25 #include "GEnergy.h"
     26 #include "GMemorySystem.h"
     27 #include "GProcessor.h"
     28 #include "Port.h"
     29 #include "Resource.h"
     30 #include "SescConf.h"
     31 
     32 #include "estl.h"
     33 
     34 // Begin: Fields used during constructions
After:
     23 #include "Cluster.h"
     24 
     25 #include "GEnergy.h"
     26 #include "GMemorySystem.h"
     27 #include "GProcessor.h"
     28 #include "Port.h"
     29 #include "Resource.h"
     30 #include "SescConf.h"
     31 
     32 #include "estl.h"
     33 
     34 #include <limits.h>
     35 
     36 // Begin: Fields used during constructions
ファイルの修正を終え,再度makeを叩く.

しかし前進はしているもののまたしてもエラー(結果からいえば次が最後の修正だった).

/home/user/00_workspace/sesc/./src/libsuc/Config.cpp:211:
error: ‘LONG_MAX’ was not declared in this scope
/home/user/00_workspace/sesc/./src/libsuc/Config.cpp: In
member function ‘bool Config::isPower2(const char*, const char*,
int32_t)’:
/home/user/00_workspace/sesc/./src/libsuc/Config.cpp:762:
error: ‘uint32_t’ was not declared in this scope
/home/user/00_workspace/sesc/./src/libsuc/Config.cpp:762:
error: expected ‘;’ before ‘v’
/home/user/00_workspace/sesc/./src/libsuc/Config.cpp:764:
error: ‘v’ was not declared in this scope
/home/user/00_workspace/sesc/./src/libsuc/Config.cpp:771:
error: ‘v’ was not declared in this scope
make[1]: ***
[/home/user/00_workspace/sesc/obj/Linux_obj/Config.o] エラー 1
今度はいろいろとエラーが出ているが,そのうち一つはまたしてもlimits.hが原因だった(結果としてはなんとかなったが,やはり読み込まない原因を最初に確認すべきだったかもしれない).LONG_MAXはlimits.hで定義されたマクロであるため,同様の文をConfig.cppに追加する.また,以降のエラーは恐らくuint32_tが原因で連鎖的に起きてそうな気がするので,そこだけ修正する.EGREPコマンドで確認したところ,uint32_tはplist/plist.hで定義されているのは分かったが,これだけ読み込んでも意味がなかった.ネットで調べたところstdint.hを読み込めば良いらしいので,これを読み込むように修正する.この型を使うこと自体C++では推奨されていないようだったが,typedef unsigned int uint32_t;のようなプロセッサに依存する書き方よりはマシかと思い,素直にstdint.hを取り込む方法をとる.
Before:
     28 #include 
     29 #include 
     30 
     31 #include "alloca.h"
     32 #include "Config.h"
     33 #include "ReportGen.h"
     34 
     35 Config::Record::~Record(void){
After:
     28 #include 
     29 #include 
     30 
     31 #include "alloca.h"
     32 #include "Config.h"
     33 #include "ReportGen.h"
     34 
     35 #include <limits.h>
     36 #include <stdint.h>
     37 
     38 Config::Record::~Record(void){
修正後,再びコンパイルし,ようやくmakeが無事終了した.

設定ファイルのコピー

以上まででプログラムは完成しているが,実際に実行するためには設定ファイルが必要である.設定ファイルは自分で書くか,コピーするか,MAKEコマンドによって自動で最適なものをコピーする方法がある.もちろん初めてなのでMAKEコマンドを使う.

make sesc.conf
Generating sesc.conf from:
/home/user/00_workspace/sesc/./confs/mem.conf
cp /home/user/00_workspace/sesc/./confs/mem.conf sesc.conf
cp /home/user/00_workspace/sesc/./confs/shared.conf .

実行確認

実行確認もまたMAKEコマンドで行える.オプションを指定することで,プログラムの呼び出しや引数指定を行ってくれるのだ.

user% make testsim
make[1]: `sesc.mem' は更新済みです
./sesc.mem -h0x800000 -csesc.conf
/home/user/00_workspace/sesc/./tests/crafty <
/home/user/00_workspace/sesc/./tests/tt.in
static[0x1008db40-0x101b3dd4] heap[0x101b4000-0x109b4000]
stack[0x109b4000-0x111ac000] -> [0x2b06b4000000-0x2b06b511e4c0]

Crafty v14.3

sesc_simulation_mark 0 (simulated) @30177037
White(1): sesc_simulation_mark 1 (simulated) @30226502
White(1): pondering disabled.
sesc_simulation_mark 2 (simulated) @30297741
White(1): noise level set to 0.
sesc_simulation_mark 3 (simulated) @30321294
White(1): search time set to 99999.00.
sesc_simulation_mark 4 (simulated) @30423503
White(1): verbosity set to 5.
sesc_simulation_mark 5 (simulated) @30448854
White(1): sesc_simulation_mark 6 (simulated) @30749824
White(1): search depth set to 2.
sesc_simulation_mark 7 (simulated) @30766129
White(1): 
              clearing hash tables

              depth   time  score   variation (1)
                1   ###.##  -0.67   axb5 c6xb5
                1   ###.##  -0.08   a4a5
sesc_simulation_mark 8 (simulated) @33088601
                1-> ###.##  -0.08   a4a5
                2   ###.##     --   a4a5
                2   ###.##  -0.65   a4a5 f6f5
                2   ###.##  -0.58   axb5 c6xb5 Ne4c5
                2   ###.##  -0.46   Rf1c1 f6f5
                2   ###.##  -0.43   Ra1c1 f6f5
sesc_simulation_mark 9 (simulated) @37835727
                2-> ###.##  -0.43   Ra1c1 f6f5
              time:###  cpu:###  mat:-1  n:833  nps: ####
              ext-> checks:18 recaps:4 pawns:0 1rep:6
              predicted:0  nodes:833  evals:372
              endgame tablebase-> probes done: 0  successful: 0
              hashing-> trans/ref:17%  pawn:83%  used:w0% b0%

White(1): Ra1c1 
              time used: ###.##
sesc_simulation_mark 10 (simulated) @38876482
Black(1): execution complete.

以上でオプションを指定しない場合のSESCのコンパイルは終了である.

sescutilsのコンパイル

投稿日:
タグ:

SESCのためのクロスコンパイラと他もろもろをコンパイル. 環境はSESCのコンパイルと同じ. 構築にはsescutilsという必要なソースとそれをコンパイルするためのスクリプトをまとめたものがあったので,それを利用した. 普通クロスコンパイラの構築には,シミュレートするISAなりエンディアンなりOSの情報なりが必要だが,そのあたりはスクリプトで設定されていたので,コンパイルを通すことだけに集中できた(一応事前にいろいろ調べたが). ただし私はこんなスクリプトを使ったのは初めてだったので,configureのエラーなのかmakeのエラーなのかが一瞬分かり辛かったりする弊害があった.

はじめに

説明は$HOME/workspace/に必要なものを解凍するところから始める.

uesr% tar jxf sescutils.tar.bz2
user% cd sescutils
全体の流れとしては,README.sescに書かれた通りに行う. ただしテキストで使用しているスクリプトの名前と実際のファイル名が微妙に違ったりする(というかテキストとスクリプトの名前が違うのはどうなんだろうか).
user% cd build-mipseb-linux/  
user% ls

build-1-binutils  build-3-glibc  build-5-gdb   build-gmp
build-2-gcc-core  build-4-gcc build-common
各スクリプトの名前には番号が降られており,基本的にこの順番に実行していけば良い. ただし今回はgdbのコンパイルは行わない. これらのスクリプトはsourceコマンドでbuild-commonにある変数を読み込み,それに従って実行する. そのため,README.sescの説明にもあるがbuild-commonの中身を自分用に書き換える必要がある.
Before:
      1 #!/bin/sh
      2 
      3 # common paths
      4 GNUSRC=$HOME/projs/gnu/src
      5 PREFIX=$HOME/projs/gnu/install
      6 PATH=$PREFIX/bin:$PATH
      7 KERNHEADERS=$GNUSRC/linux-headers
      8 
      9 # common parameters
     10 BUILD="`uname -p`-`uname -s | sed s/Linux/linux/ | sed
      s/Darwin/darwin/`"
After:
      1 #!/bin/sh
      2 
      3 # common paths
      4 GNUSRC=$HOME/workspace/sescutils/src
      5 PREFIX=$HOME/mypath
      6 PATH=$PREFIX/bin:$PATH
      7 KERNHEADERS=$GNUSRC/linux-headers
      8 
      9 # common parameters
     10 BUILD="`uname -p`-`uname -s | sed s/Linux/linux/ | sed
     s/Darwin/darwin/`"

binutils

1つ目はbinutilのコンパイル. 結論からいうとbinutilsは,コンパイル自体に手間はなかった. ただしconfigureやmakeを実行する前のスクリプトで躓いた.

user% ./build-1-binutils

./build-1-binutils: 3: source: not found
./build-1-binutils: 12: /binutils/configure: not found
./build-1-binutils: 13: all: not found
開始してすぐsourceがないと言われた. しかし,実行するシェルをZSHに変えたら即解決.
user% zsh ./build-1-binutils
スクリプト終了と共にprefixで指定した先にobjdumpなどのマニュアルやプログラムがインストールされる. 他のスクリプトも同様にsourceを使用しているので,zshで起動する.

gcc-core

2つ目はgcc-coreのコンパイル.

user% zsh ./build-2-gcc-core
	・
	・
	・
gcc -c   -g -O2 -DIN_GCC -DCROSS_COMPILE  -W -Wall -Wwrite-strings
-Wstrict-prototypes -Wmissing-prototypes -pedantic -Wno-long-long
-Wno-error  -DHAVE_CONFIG_H
-I. -I. -I/home/user/workspace/sescutils/src/gcc-3.4/gcc/gcc
-I/home/user/workspace/sescutils/src/gcc-3.4/gcc/gcc/. -I/home/user/workspace/sescutils/src/gcc-3.4/gcc/gcc/../include
c-parse.c -o c-parse.o
gcc: c-parse.c: そのようなファイルやディレクトリはありません
gcc: no input files
make[1]: *** [c-parse.o] エラー 1
make[1]: ディレクトリ
`/home/user/workspace/sescutils/build-mipseb-linux/obj/gcc-core-build/gcc'
から出ます
make: *** [all-gcc] エラー 2
スクリプトの出力を読んでいくと,無視されているエラーを発見(ここには載せてない部分). エラーはコンパイラコンパイラのBISONが原因だった. どうやらBISONの古いバージョンで読み取れていたものが新しいバージョンになって読み取れなくなったらしい(そうなった経緯は知らないが). BISONは前に扱う機会があったが,もう忘れているので素直にWEBで検索した. http://www.microchip.com/forums/m416697-print.aspx

BISONのソースコード(../src/gcc-3.4/gcc/gcc/c-parse.in)を書き換える.

Before:
   1731 structsp_attr:
   1732     struct_head identifier '{'
   1733     { $$ = start_struct (RECORD_TYPE, $2);
   1734       /* Start scope of tag before parsing components.  */
   1735     }
   1736     component_decl_list '}' maybe_attribute
   1737     { $$ = finish_struct ($<ttype>4, nreverse ($5),
   1738               chainon ($1, $7)); }
   1739   | struct_head '{' component_decl_list '}' maybe_attribute
   1740     { $$ = finish_struct (start_struct (RECORD_TYPE, NULL_TREE),
   1741               nreverse ($3), chainon ($1, $5));
   1742     }
   1743   | union_head identifier '{'
   1744     { $$ = start_struct (UNION_TYPE, $2); }
   1745     component_decl_list '}' maybe_attribute
   1746     { $$ = finish_struct ($<ttype>4, nreverse ($5),
   1747               chainon ($1, $7)); }
   1748   | union_head '{' component_decl_list '}' maybe_attribute
   1749     { $$ = finish_struct (start_struct (UNION_TYPE, NULL_TREE),
   1750               nreverse ($3), chainon ($1, $5));
   1751     }
   1752   | enum_head identifier '{'
   1753     { $$ = start_enum ($2); }
   1754     enumlist maybecomma_warn '}' maybe_attribute
   1755     { $$ = finish_enum ($<ttype>4, nreverse ($5),
   1756             chainon ($1, $8)); }
   1757   | enum_head '{'
   1758     { $$ = start_enum (NULL_TREE); }
   1759     enumlist maybecomma_warn '}' maybe_attribute
   1760     { $$ = finish_enum ($<ttype>3, nreverse ($4),
   1761             chainon ($1, $7)); }
After:
   1731 structsp_attr:
   1732     struct_head identifier '{'
   1733 //    { $$ = start_struct (RECORD_TYPE, $2);
   1734     { $<ttype>$ = start_struct (RECORD_TYPE, $2);
   1735       /* Start scope of tag before parsing components.  */
   1736     }
   1737     component_decl_list '}' maybe_attribute
   1738     { $$ = finish_struct ($<ttype>4, nreverse ($5),
   1739               chainon ($1, $7)); }
   1740   | struct_head '{' component_decl_list '}' maybe_attribute
   1741     { $$ = finish_struct (start_struct (RECORD_TYPE, NULL_TREE),
   1742               nreverse ($3), chainon ($1, $5));
   1743     }
   1744   | union_head identifier '{'
   1745 //    { $$ = start_struct (UNION_TYPE, $2); }
   1746     { $<ttype>$ = start_struct (UNION_TYPE, $2); }
   1747     component_decl_list '}' maybe_attribute
   1748     { $$ = finish_struct ($<ttype>4, nreverse ($5),
   1749               chainon ($1, $7)); }
   1750   | union_head '{' component_decl_list '}' maybe_attribute
   1751     { $$ = finish_struct (start_struct (UNION_TYPE, NULL_TREE),
   1752               nreverse ($3), chainon ($1, $5));
   1753     }
   1754   | enum_head identifier '{'
   1755 //    { $$ = start_enum ($2); }
   1756     { $<ttype>$ = start_enum ($2); }
   1757     enumlist maybecomma_warn '}' maybe_attribute
   1758     { $$ = finish_enum ($<ttype>4, nreverse ($5),
   1759             chainon ($1, $8)); }
   1760   | enum_head '{'
   1761 //    { $$ = start_enum (NULL_TREE); }
   1762     { $<ttype>$ = start_enum (NULL_TREE); }
   1763     enumlist maybecomma_warn '}' maybe_attribute
   1764     { $$ = finish_enum ($<ttype>3, nreverse ($4),
   1765             chainon ($1, $7)); }
書き換え後再びスクリプトを実行し,無事終了した.

glibc

3つ目はglibcのコンパイル. 先に言うとglibcの2箇所の修正を行う.

user% zsh build-3-glibc
checking build system type... Invalid configuration `unknown-linux':
machine `unknown' not recognized
configure: error: /bin/bash
/home/user/workspace/sescutils/src/glibc-2.3.2/scripts/config.sub
unknown-linux failed
make: *** ターゲット `all' を make するルールがありません.  中止.
構築対象のマシンが分からないと言われた. ぱっと見修正箇所が分からなかったので調べてみた. 原因はbuild-3-glibcのBUILD変数の値だった(World's Appreciated Kitsh!より). このページではBUILD変数をi686-linuxに書き換えていたが,自分の環境ではgccのvオプションでがx86_64-linux-gnuになっていたので,それに書き換えた.
Before:
      1 #!/bin/sh
      2 
      3 source ./build-common
      4 
      5 GLIBC=glibc-2.3.2
      6 GLIBC_THREADS=glibc-linuxthreads-2.2.5
      7 GLIBC_HEADERS=glibc-kernheaders-2.4.15pre9
      8 GLIBC_BUILD_DIR=obj/glibc-build
      9 
     10 rm -rf $GLIBC_BUILD_DIR
     11 mkdir -p $GLIBC_BUILD_DIR
     12 cd $GLIBC_BUILD_DIR
     13 export CFLAGS="-O2 -mips2 -mabi=32 -fno-PIC -mno-abicalls"
     14 export CZFLAGS="-mips2 -mabi=32 -fno-PIC -mno-abicalls"
     15 $GNUSRC/$GLIBC/configure --build=${BUILD} --host=${TARGET}
      --prefix=${PREFIX}/${TARGET} \
     16   --disable-shared --with-headers=$KERNHEADERS --enable-add-ons
      --enable-static-nss \
     17   --disable-profile 2>1 | tee ../glibc.conf.log
     18 $MAKE all install 2>1 | tee ../glibc.gmake.log
     19 cd ../..
     20 
After:
      1 #!/bin/sh
      2 
      3 source ./build-common
      4 
      5 GLIBC=glibc-2.3.2
      6 GLIBC_THREADS=glibc-linuxthreads-2.2.5
      7 GLIBC_HEADERS=glibc-kernheaders-2.4.15pre9
      8 GLIBC_BUILD_DIR=obj/glibc-build
      9 
     10 rm -rf $GLIBC_BUILD_DIR
     11 mkdir -p $GLIBC_BUILD_DIR
     12 cd $GLIBC_BUILD_DIR
     13 export CFLAGS="-O2 -mips2 -mabi=32 -fno-PIC -mno-abicalls"
     14 export CZFLAGS="-mips2 -mabi=32 -fno-PIC -mno-abicalls"
     15 $GNUSRC/$GLIBC/configure --build=x86_64-linux-gnu --host=${TARGET}
      --prefix=${PREFIX}/${TARGET} \
     16   --disable-shared --with-headers=$KERNHEADERS --enable-add-ons
      --enable-static-nss \
     17   --disable-profile 2>1 | tee ../glibc.conf.log
     18 $MAKE all install 2>1 | tee ../glibc.gmake.log
     19 cd ../..
     20 

修正して再びコンパイルするも,また失敗.

	・
	・
	・
In file included from version.c:33:
/home/user/workspace/sescutils/build-mipseb-linux/obj/glibc-build/csu/version-info.h:1:
	error: missing terminating " character
/home/user/workspace/sescutils/build-mipseb-linux/obj/glibc-build/csu/version-info.h:2:
	error: missing terminating " character
/home/user/workspace/sescutils/build-mipseb-linux/obj/glibc-build/csu/version-info.h:3:
	error: missing terminating " character
/home/user/workspace/sescutils/build-mipseb-linux/obj/glibc-build/csu/version-info.h:4:
	error: missing terminating " character
version.c:40: error: syntax error before string constant
make[2]: ***
	[/home/user/workspace/sescutils/build-mipseb-linux/obj/glibc-build/csu/version.o]
	エラー 1
make[2]: ディレクトリ
	`/home/user/workspace/sescutils/src/glibc-2.3.2/csu'
	から出ます
make[1]: *** [csu/subdir_lib] エラー 2
make[1]: ディレクトリ
	`/home/user/workspace/sescutils/src/glibc-2.3.2' か
	ら出ます
make: *** [all] エラー 2
verion-info.hが原因らしいが,今度もまた分かり辛いエラーだった. しかし,幸いこれも同様に先ほどのページに解決方法が書いてあった. ../src/glibc-2.3.2/csu/version.cのversion-info.hを取り込む部分をコメントアウトするだけで良いらしい(普通こんなことしたらコンパイルが通らなそうだが結果から言えばコンパイルが通った上に今のところ実行にも支障はない).
Before:
     32 Compiled by GNU CC version "__VERSION__".\n"
     33 #include "version-info.h"
     34 #ifdef GLIBC_OLDEST_ABI
     35 "The oldest ABI supported: " GLIBC_OLDEST_ABI ".\n"
     36 #endif
After:
     32 Compiled by GNU CC version "__VERSION__".\n"
     33 //#include "version-info.h"
     34 #ifdef GLIBC_OLDEST_ABI
     35 "The oldest ABI supported: " GLIBC_OLDEST_ABI ".\n"
     36 #endif

gcc

最後にgccのコンパイルを行ったが,これは何のトラブルもなかったので省略する.

実行確認

以上まででクロスコンパイラの構築は終わりで,次からはクロスコンパイラが正常かのテストである. 冗長に関数を使ったコードを書いてコンパイルし,それをsescで実行してみた. 実行したソースコードは以下の通りである.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char &argv[])
{
  write(1, "Hello, World\n", strlen("Hello, World\n"));
  exit(0);
  return 0;
}
PATHを通し,いざコンパイル. README.sescによると,gccに使用するオプションを加えたものが次の通りである.
user% mipseb-linux-gcc -mips2 -mabi=32 -Wa,-non_shared
-mno-abicalls --static
-Wl,--script=/home/user/mypath/mipseb-linux/lib/ldscripts/mint.x 
試しに実行すると無事コンパイルもsescでの実行もできたので,引数を受け取れるように変更して.zshrcに加えた.

SESCでのマルチコアプロセッサのシミュレーション

投稿日:
タグ:

SESCで複数のコアで複数のスレッド(またはプロセス)を同時実行しようとした時のことをメモ.結論からいうとこの記事は調査不足のまま書いているが,一応メモしておくことにした.今回の内容で主に参考にした情報源はDongrui's Homepageあるメール である.

マルチコアを使用するためのAPI

1つのプログラムで複数のスレッドを持つようなプログラムはSESCが提供するAPIを使用して記述することができる. そのAPIは"src/libapp/sesc_thread.c"で定義されており,"src/libapp/sescapi.h"を取り込み,先のCファイルから生成したオブジェクトとリンクすればAPIを利用できる. APIについては"docs/README.libapp"や"sescapi.h"で説明されている.

sescapi.hの一部(...は省略)
void sesc_init(void);
...
int32_t  sesc_spawn(void (*start_routine) (void *), void *arg, int32_t flags);
...
void sesc_exit(int32_t err);
これらのAPIは中でpthreadによって何か行われているらしく,提供される関数も同様なものだった.APIを使用したコードは次のようになる.
#include <stdio.h>
#include "sescapi.h"
#define THREADS_NUM        4
 
void *hello(void *arg)
{
  printf("Hello World!\n");
  sesc_exit(0);
  return NULL;
}
  
int main()
{
  int i;
  sesc_init();
  for(i=0; i<THREADS_NUM; i++){
    sesc_spawn((void*) *hello, NULL, SESC_FLAG_NOMIGRATE|SESC_FLAG_MAP|i);
  }
  sesc_exit(0);
  return 0;
}
これが書かれたファイルは"sescapi.h"と"sesc_thread.o"と同じディレクトリにあるものとする. コードの説明らは省略するが,これをクロスコンパイルしたものをSESCで実行した後,前と同様にレポートを出力する.
user% ./scripts/report.pl -last

# Bench : ./sesc.mem ./test/test2 
# File  : sesc_test2.yCPolo    :       Sun Aug 26 04:25:10 2012
      Exe Speed        Exe MHz         Exe Time         Sim Time
      (5000MHz)
    720.300 KIPS      7.3911 MHz       0.010 secs       0.015 msec
Proc  Avg.Time BPType       Total          RAS           BPred
BTB            BTAC
   0   252.198  hybrid       54.03% (100.00% of  10.63%)  48.56% (
   48.77% of  34.82%)   0.00% 
   1   239.483  hybrid       61.07% (100.00% of   9.06%)  57.20% (
   49.58% of  39.93%)   0.00% 
   2   239.069  hybrid       61.07% (100.00% of   9.06%)  57.20% (
   49.58% of  39.93%)   0.00% 
   3   238.655  hybrid       61.07% (100.00% of   9.06%)  57.20% (
   49.58% of  39.93%)   0.00% 
           nInst     BJ    Load   Store      INT      FP  : LD Forward ,
	   Replay : Worst Unit (clk)
   0        2925  19.93%  19.93%  12.41%  47.66%   0.07%  :     13.04%
   731 inst/repl  :  ALUIssueX 0.06 
   1        1426  20.90%  23.63%  13.88%  41.58%   0.00%  :     19.58%
   713 inst/repl  :  ALUIssueX 0.09 
   2        1426  20.90%  23.63%  13.88%  41.58%   0.00%  :     19.58%
   713 inst/repl  :  ALUIssueX 0.09 
   3        1426  20.90%  23.63%  13.88%  41.58%   0.00%  :     20.18%
   713 inst/repl  :  ALUIssueX 0.09 
Proc  IPC  Active       Cycles  Busy   LDQ   STQ  IWin   ROB  Regs Ports
TLB  maxBr MisBr Br4Clk  Other
   0  0.04  99.98        73898   1.3   0.0   0.0   0.1   0.0   0.0   0.0
   10.6   0.0   87.9    0.0    0.1 
   1  0.05  41.47        30651   1.6   0.0   0.0   0.1   0.0   0.0   0.0
   6.9   0.0   91.3    0.0    0.1 
   2  0.05  41.41        30604   1.6   0.0   0.0   0.1   0.0   0.0   0.0
   6.9   0.0   91.2    0.0    0.1 
   3  0.05  41.34        30556   1.6   0.0   0.0   0.1   0.0   0.0   0.0
   7.0   0.0   91.2    0.0    0.1 
################################################################################
Proc  Cache Occ MissRate (RD, WR) %DMemAcc MB/s : ... 
   0  DL1 0.0   6.24% ( 3.7%, 2.5%) 37.70%  0.26GB/s :  Bus 749.009 MB/s
   : L2 0.0  43.22% (43.2%, 0.0%) 18.50%  0.88GB/s :  MemBus 883.224
   MB/s : 
   1  DL1 0.0   7.02% ( 4.7%, 2.3%) 20.10%  0.16GB/s :  Bus 749.009 MB/s
   : L2 0.0  43.22% (43.2%, 0.0%) 18.50%  0.88GB/s :  MemBus 883.224
   MB/s : 
   2  DL1 0.0   7.21% ( 4.9%, 2.3%) 20.10%  0.16GB/s :  Bus 749.009 MB/s
   : L2 0.0  43.22% (43.2%, 0.0%) 18.50%  0.88GB/s :  MemBus 883.224
   MB/s : 
   3  DL1 0.0   7.11% ( 4.7%, 2.4%) 19.83%  0.16GB/s :  Bus 749.009 MB/s
   : L2 0.0  43.22% (43.2%, 0.0%) 18.50%  0.88GB/s :  MemBus 883.224
   MB/s : 
################################################################################
Proc  Cache Occ MissRate (RD, WR) %DMemAcc MB/s : ... 
   0  IL1 0.0  19.65% (19.7%, 0.0%) 26.92%  0.58GB/s : L2 0.0  43.22%
   (43.2%, 0.0%) 18.50%  0.88GB/s :  MemBus 883.224 MB/s : 
   1  IL1 0.0  16.67% (16.7%, 0.0%) 13.17%  0.24GB/s : L2 0.0  43.22%
   (43.2%, 0.0%) 18.50%  0.88GB/s :  MemBus 883.224 MB/s : 
   2  IL1 0.0  16.67% (16.7%, 0.0%) 13.17%  0.24GB/s : L2 0.0  43.22%
   (43.2%, 0.0%) 18.50%  0.88GB/s :  MemBus 883.224 MB/s : 
   3  IL1 0.0  16.67% (16.7%, 0.0%) 13.17%  0.24GB/s : L2 0.0  43.22%
   (43.2%, 0.0%) 18.50%  0.88GB/s :  MemBus 883.224 MB/s : 
このように複数のコアを動かすこと自体は成功した.

既存のプログラムに対して

元々あるマルチスレッドプログラムを使う場合はどうするか,または複数のプログラムをどうやって並列して動かすか(そもそもそれができるのか)は結局まだ分かっていない.そこで,とりあえず複数のプログラムのソースコードを持ってきてmain関数を別の関数名に置き換え,新しく用意したmain関数付きのオブジェクトとリンクさせることにしてみた.こうすれば,前述で示した方法で複数のコアを使用することができると思ったからだ.結果はここに載せないが,一応この方法を用いれば複数のプログラムをそれぞれのコアで実行することはできた(色々と気になることはあるが). ちなみにこの方法を用いる前にexec関数らを使った方法を試みたが,それらの関数はSESCで実装されていなかったため上手くいかなかった.

一覧