第 5 章 性能評価シミュレータとバイナリ変換技術
5.3. ESPRIT/ SIM
ある.
・ 互換エミュレータ並みのバイナリ変換の信頼性は必須ではない.
・ エミュレータでは従来使用してきた機種より処理が遅いとその存在価値が薄れるが,性 能評価目的のシミュレータでは性能に対する厳密な指標がないためインタプリタより 数倍高速なだけでもその価値はある.
したがって,性能評価シミュレータのバイナリ変換への取組みは,エミュレータ用途のバ イナリ変換に比べて容易となる.
5.2.5. 性能評価シミュレータの高速化に関する課題
一方,性能評価を目的としたシミュレーションゆえに次の点が新たな課題となる.
・ 性能評価のためだけにバイナリ変換機能の開発に多大なコストを掛けられない.
・ ある程度の品質を確保しないとシミュレーションができないため,バイナリ変換の導入 の敷居は高くなる.
・ 複数の命令セットの CPU が混載可能なシミュレータの開発では,CPU を供給してい
るコンピュータメーカが異なるため必要な命令セットのバイナリ変換機構を取り揃え るのは困難となる.
・ 性能評価に必要な命令数などの情報やマルチプロセッサシミュレーション時のCPUの
切替え処理などが別途必要となる.
つ.入力には,キャッシュミスやメモリなどのアクセスペナルティ及びキャッシュメモリ 構成のようなパラメータ,並びにアプリケーションのバイナリがある.出力は回数や時間 情報などボトルネックを示す情報である.
Performance Analysis
Application Application
Binary
Definition Data
・Penalty Cycles
・H/W organization
出 力 Simulator Core
(H/W Independent)
I/O simulator
Cache model Memory model
Bus model
Performance Simulator ESPRIT/sim
Analysis & Reporting
H/W Depend ent
Result
・Penalties
・bottle-neck
・Performance forecast after improvement
Statistics
……….
…...
Inputs
Instruction Emulator
Cache model
Performance Analysis
Application Application
Binary
Definition Data
・Penalty Cycles
・H/W organization
出 力 Simulator Core
(H/W Independent)
I/O simulator
Cache model Memory model
Bus model
Performance Simulator ESPRIT/sim
Analysis & Reporting
H/W Depend ent
Result
・Penalties
・bottle-neck
・Performance forecast after improvement
Statistics
……….
…...
Inputs
Instruction Emulator
Cache model
図32 ESPRIT/simの処理イメージ
統計情報として次のようなものが採取できる.
・ 命令実行回数
・ クロックサイクル数
・ 命令の種類と実行回数
・ メモリアクセス(読書き,ページ,記憶素子)回数
・ キャッシュメモリアクセス(ヒット,ミス,ライトバック,無効化)回数
・ TLBアクセス(ヒット,ミス,無効化,パージ)回数
・ 関数(呼出し回数,命令数,サイクル数,キャッシュヒット/ミス数,TLB ヒット/
ミス数,関数の親子単位の呼出し回数)
・ 分岐(実行,成立/非成立)回数,アドレスごとの同回数
・ 分岐予測(ヒット/ミス)回数
・ パイプライン(事象ごとの回数,事象ごとのオーバヘッドサイクル数)
run-loop
Systemcall Simulator
PC (Windows), PC(linux), EWS(Solaris,OSX) Registers
InsFnc
Instr decoders
:
Statistics (functions, branches, memory, cache, bus, data, etc.)
ISA-A ISA-B
InsFnc
InsFnc Memory App Loaders
Cache
Results
Load mod
run-scheduler(for MP) I/O simulator
図33 ESPRIT/simの構成
ESPRIT/simの構成を図33に示す.本シミュレータは,命令セットアーキテクチャ(ISA)
ごとに各命令に対応した命令処理関数(InsFnc)とデコーダ及びインタプリタの処理を繰り 返すコアループ(run_loop)を持つ.レガシーISAのレジスタやキャッシュメモリはCPUご とに持つ.共通なものとして,メモリ,I/O シミュレータ,システムコールシミュレータ,
統計機構,コマンドインタプリタ,ローダなどがある.複数CPU構成時やI/O動作時には スケジューラ(run-scheduler)がrun-loopの切り替えを行う.
Functionality
Accuracy Speed
(e) Cycle accurate Pipeline (a)Binary
Translation
(c)General-sim
(b)Fast-sim [Setup]
Fast Accurate
(d)Simple-pipe
(a/b) (c) (d/e) [Warming-up]
[Analysis]
Functionality
Accuracy Speed
(e) Cycle accurate Pipeline (a)Binary
Translation
(c)General-sim
(b)Fast-sim [Setup]
Fast Accurate
(d)Simple-pipe
(a/b) (c) (d/e) [Warming-up]
[Analysis]
図34 ESPRIT/simのシミュレーションコアの特性と使い方
シミュレータコアには,採取する統計機能を限定した高速インタプリタと,統計対象を 個別に選択できる解析用シミュレータを標準装備している.更に,インオーダ命令発行を モデル化した簡易パイプラインシミュレータと,アウトオブオーダ命令発行/投機命令実 行/命令プリフェッチが扱える詳細パイプラインシミュレータがあるが,それらの実装の 有無は ISA 依存である.これらは,それぞれ別のコアループとして実装されている.
ESPRIT/simは複合型のシミュレータで,図34に各シミュレータコアの特性と使い方のイ
メージを示す.実行速度(Speed),機能(Functionality),精度(Accuracy)は相反する ものである.バイナリ変換(a)または高速インタプリタ(b)は速度重視のときに使用し,
(d, e)パイプラインシミュレータは精度を重視するときに用いる.各種の統計を採る,CPU 内部よりキャッシュメモリやメモリおよびバス周りの遅延が支配的な場合は(c)の解析用 インタプリタを使用する.組み合わせて使う場合は図の右側に示したように,(a)または
(b)でプログラム動作の立ち上げ,(c)でキャッシュメモリの状態を反映し,(d)または
(e)で詳細な解析を行うという順に使う.
ESPRIT/simがシミュレーション対象としているISA(レガシーISA)には,次のものな
どがある.
・ PowerPC
・ MIPS32/64
・ SH4
・ M32R/M32RII
・ SimpleScalar/PISA
ホストISAには,x86(Windows,Cygwin,Linux),Sparc(Solaris),PowerPC(OSX)
がある.
proc_ppc7450 proc_ppc750
isa_family isa
isa_m32r_family isa_ppc_family
isa_ppc6xx isa_ppc7XX processor_element
cache I$ D$ S$
regs
CacSim InsSim DisAsm
図35 ESPRIT/simのクラスの例
図35にESPRIT/simのモデル記述で使用しているクラスの関係を示す.各プロセッサは
processor_element と isa_*の両方の派生クラスとして proc_*に定義される.isa_*は命令
セット依存の処理を,processor_elementはハードウェアの実体を受け持つ.同じCPUの シリーズでもキャッシュメモリの構成が異なるものは proc_*ごとにカストマイズできる.
各CPUの処理は基本クラスprocessor_elementのポインタから仮想関数としてアクセスさ れ ,proc_*の メ ン バ ー 関 数 ,isa_*の メ ン バ ー 関 数 の 順 に ア ク セ ス さ れ る . 次 に
processor_elementクラス,isaの派生クラス及びproc_*クラスの定義例を示す.
processor_elementクラスの定義例 class processor_element {
protected:
public:
processor_element();
char *processor_type_name;
class isa_family *isa_fam;
class isa *isa_ptr;
:
struct mpc_regs_dummy_s regs; // 各ISAごとのレジスタ定義 unsigned long pc, pc_real;
class cache_memory *i_cacp, *d_cacp, *s_cacp; // キャッシュメモリへのポインタ struct code_cache_control_s cc_ctrl; // コード変換キャッシュの制御とポインタ struct ins_def_s virtual *get_decode_ptr
(unsigned long code, unsigned long addr) = 0; //命令デコーダ
void virtual translate(unsigned long addr) = 0; // 命令列のバイナリ変換を起動 bool translate_unit_instr_isa(unsigned long *lc, int cc_ix);
// 命令1個のバイナリ変換
int virtual run_dbt_core(int cnt, int *cont) = 0; // バイナリ変換モードのrun_loop void virtual run_fast_core(int cnt, int *cont) = 0; // 高速インタプリタのrun_loop
void virtual run_normal_core(int cnt, int *cont) = 0;// 解析用インタプリタのrun_loop :
int virtual print_instr(char *s, unsigned long code, unsigned long adr, unsigned long code2 = 0) = 0;
}
isaの派生クラスの定義例 class isa_ss_pisa: public isa, isa_ss_pisa_family { public:
isa_ss_pisa();
struct ins_def_s *get_decode_ptr_isa(unsigned long code, unsigned long addr);
void translate_isa(unsigned long addr) { cpe->translate_common(addr); } bool translate_unit_instr_isa(unsigned long *lc, int cc_ix);
int run_dbt_isa_core(int cnt, int *cont);
void run_fast_isa_core(int cnt, int *cont);
void run_normal_isa_core(int cnt, int *cont);
:
int print_instr_isa(char *s, unsigned long code_upper, unsigned long code_lower, unsigned long adr);
}
proc_ss_pisaクラスの定義例
class proc_ss_pisa: public processor_element, isa_ss_pisa { public:
void translate(unsigned long addr) { translate_isa(addr); } bool translate_unit_instr(unsigned long *lc, int cc_ix) { return translate_unit_instr_isa(lc, cc_ix);}
int run_dbt_core(int cnt, int *cont) { return run_dbt_isa_core(cnt, cont);}
void run_fast_core(int cnt, int *cont) { run_fast_isa_core(cnt, cont); } void run_normal_core(int cnt, int *cont){ run_normal_isa_core(cnt, cont);
:
int print_instr(char *s, unsigned long code, unsigned long adr, unsigned long code2 = 0)
{ return print_instr_isa(s, code, code2, adr); } }
図 36に,ESPRIT/sim に実装した動的バイナリ変換の処理フローを示す.コード変換
キャッシュ(CC)は,レガシー命令アドレス,ホスト命令アドレスのペアからなるディレ クトリ (CCD)とホスト命令列を格納した配列 (CCE)から構成される.実行頻度を計 数するカウンタディレクトリ(CTD)の値が閾値を超すとトランスレータを呼び出す.変 換済みのコードが見つかった場合は CCE 内のホストコードに分岐する.CCE から溢れる か分岐が成立すると,このループに戻るようにホストコードは生成される.インタプリタ が実行されるとき,図中の“Interpreter”が命令デコード後にInsFncを呼び出す.すなわ ち,インタプリタとトランスレータのそれぞれのコアループが密結合した一体構造が採用 されている.付録にSimpleScalar/PISA用のrun_loop部のコードを示す.
なお,ESPRIT/simはコンパイラ依存のインラインアセンブルや C言語の方言は原則的 に使用していない.例外は,ホストPowerPC用のキャッシュの無効化処理と,ホストx86
のRDTSC (Read Time-Stamp Counter)命令を使用した正確な時間測定を行うインライ
ンアセンブル関数のみである.
N
Translator Translated
code in CCD?
Check PC ≦ max Lookup CCD by PC
Add(replace)to CTD
Interpreter PC in CTD?
++ counter > threshold
run_loop
Branch to CCE Y
N N
Y
Y
CC: code translation cache CCD: code cache directory CCE: code cache entry CTD: counter directory PC: program counter
branch taken?
N
Y CCD ⇔ CTD
Direct branch (Uni-processor option)
図36 動的バイナリ変換の処理フロー図