Symbolic Bounds Analysis of Pointers, Array Indices, and Accessed

Download Report

Transcript Symbolic Bounds Analysis of Pointers, Array Indices, and Accessed

Symbolic Bounds Analysis of Pointers, Array Indices, and
Accessed Memory Regions
Radu Rugina and Martin Rinard
6/6
AMOミーティング資料
M1 塩谷 沢生
Introduction
• プログラムがアクセスするメモリの領域を解析す
るアルゴリズムの提案
• データ競合の検出、配列境界のチェックの省略、
自動並列化などに利用できる
• Symbolic な解析を行う
• 並列処理を扱った論文で実際に使用した
• 念頭にあるプログラム像
– 制御構造に再帰を使用する
– 動的確保をする
– ポインタやポインタ演算を使用する
論文の構成
•
•
•
•
•
•
例題プログラムの提示
解析アルゴリズムの解説
アルゴリズムの拡張
実験
結果の応用、関連領域
結論
例題プログラム
• 与えられた配列の
先頭部分の値をイ
ンクリメントする
• 典型的な分割統
治
• Cilk (Cを並列処
理用に拡張) で記
述
解析の目標
• 各Procedure がアクセスするメモリ領域を
求めること
– メモリ領域を二通りの形式で表現する
• allocation blocks
– 確保されたメモリブロック
• symbolic regions
– あるblock中の、連続した領域
– 上限と下限がある
– シンボルを変数とする多項式(係数は有理数)
解析の例
• dcInc ( int *q, int m) の場合
– allocation block a (l.24)に対し、 symbolic
regionとして、[p0, p0 + n0 - 1] が得られる
– たとえば l.15 と l.16 でデータの競合がないこ
とを確認できる
– top-level からの呼び出し(l.26) でも、A に対し
て [A, A + size - 1 ] にしかアクセスしていない
=配列の境界を越えないことを確認できる
解析のアルゴリズム
• 目標は二つ
– プログラムの各個所において、ポインタと配列
添字変数の上限と下限を求める
– 各手続き、各allocation block 毎に、symbolic
region を求める
• これはその手続き全体がアクセスするメモリ領域を
表す
• 上限と下限はそれぞれ引数の初期値を変数とする
有理数係数の多項式で表現される
コンパイラの構成
Pointer and Read-Write Sets Analysis
• [R. Rugina and M. Rinard 99]
• ポインタをフローに従って追跡し、どの
Procedure がどのメモリ領域 にアクセス(読
みこみ・書きだし)するかを解析する
Symbolic Analysis
• まず各ポインタおよび配列変数ごとに、値
の上限と加減を求める
• 次にその結果から allocation block 上のど
の領域がアクセスされるかを求める
– Symbolic Analysis はさらに3つの手順に分か
れる
• Intraprocedural Bounds Analysis
• Intraprocedural Region Analysis
• Interprocedural Region Analysis
Symbolic Analysis の詳細
1. Intraprocedural Bounds Analysis
–
プログラムの各個所においてポインタや配列変数の
上限・下限を求める
2. Intraprocedural Region Analysis
–
1. の結果を統合し、各procedure が allocation block
のどの領域にアクセスするかを求める
3. Interprocedural Region Analysis
•
手続きの呼び出し関係も含めて、各procedure がど
の領域にアクセスするかを求める。再帰呼び出しも
ここで処理する
Intraprocedural Bounds Analysis (1/4)
初期作業
1. 対象のprocedure f を
ブロック
B = { Bj | 1 ≦ j ≦ L}
に分割する
2. 各ブロック毎、各変数
ごとに、
上限 uv,j と 下限 lv,j と
を用意する
Intraprocedural Bounds Analysis (2/4)
ブロックごとの解析
• 各指示を解釈して上限・
下限の計算をブロック毎
に行う
• 上限・下限は常に多項式
で表現する
• 条件節も利用する
• 手続きの呼び出しや、複
雑な式には無限を割り当
てる
Intraprocedural Bounds Analysis (3/4)
制約条件系の生成
• 初期化条件
– 最初のブロックB1では、ポインタ・配列添字引数 v の
上限・下限は共に v0(引数の初期値)、そうでなければ
無限大・無限小
• シンボリック制約条件
– どの変数についても、各ブロックの先頭の上限・下限
は、直前のブロックの最終の上限・下限に含まれるよ
うにする
• 目的関数
– 上限を最小化し、下限を最大化する関数、すなわち、
• min: ∑v∑lj=2 (uv,j - lv,j )
生成された制約条件系の例
Intraprocedural Bounds Analysis (4/4)
制約条件系を解く
• 上限・下限を引数を変数とする多項式で置き換
える
– li,2 = c1q0 + c2m0 + c3 li,3 = c4q0 + c5m0 + c6
• 制約条件、目的関数を係数の不等式に置換
– 例えば、上記で li,2 < li,3 なら c1<c4, c2<c5, c3<c6
– この変換を行うには、引数が正でなくてはいけないが
「シンプルな解析」を別途行ってこれを確認する
• 得られた不等式群を、線形計画法で解く
– 自由変数は Cn 、目的関数は既述
• 得られた結果を上限・下限の式に代入しなおす
置換後の制約条件系の例
• この制約条件
系から、例えば
li,3 = 0
ui, 3 =m0-1
従って 、
l.7 での変数 i
の範囲として
[0,m0 - 1]
が得られる
Region Analysis
• Intraprocedural Region Analysis
– 先に求めた上限と下限から、全ての手続き f と
allocation block a 毎にアクセス領域
RRlocalf,a とRWlocalf,a を求める
– これはメモリアクセスを行う個所ごとに、上限と下限の
指す範囲をマージしていけば良い
• Interprocedural Region Analysis
– 他の手続きを呼び出す個所(call site)ごとに、その呼
び出しでアクセスされる領域を求める
– 再帰的でない場合、呼び出し関係を逆に辿ればよい
(Symbolic Unmapping)
symbolic unmapping の例
• l.13の呼び出し
(cs1= call site 1と
呼ぶ)を
unmappingして、
SUcs1(RWbaseInc,a)
= [p0, p0 + n0 - 1]
を得る
再帰のSymbolic Unmapping(1/2)
• 不動点アルゴリズムは採用しない
– 上限・下限が収束する等比級数の場合、有限の繰り
返しではアクセスする範囲を求められない
– 静的な解析の範囲では無限にアクセス領域が増えて
しまうような関数が書ける
• Symbolic Bounds Analysis と同様、線形計画法
に帰着させる
– 呼ばれる側のアクセス領域が、呼び出し側のアクセス
領域に含まれることを制約条件に使用する
再帰のSymbolic Unmapping(2/2)
1. 再帰する手続き f のアクセス領域 RRlocalf,a と
RWlocalf,a を取得する
•
再帰終了のケース数ごとに分けて考える
RRf,a = {[lrd f,a,1, urd f,a,1]... [lrd f,a,j, urd f,a,j]}
RWf,a = {[lwr f,a,1, urd f,a,1]... [lwr f,a,j, urd f,a,j]}
2. 制約条件の生成
•
RRlocalf,a ⊆ RRf,a
•
•
SUcs(RRg,a )⊆ RRf,a
•
•
ローカルな領域はグローバルな領域に含まれる
呼ばれる側は呼ぶ側の領域にふくまれる
これらの制約条件の下で、上限と下限の差が最小
になるように線型計画法で解く
再帰のSymbolic Unmappingの例
• dcInc の例
• l13, l15, l16 の呼び出し
から制約条件を生成する
•dcInc は直接 allocated
block にアクセスしないの
で、呼び出しからしか制約
を生成できない
•lwrdcInc,a = p0, uwrdcInc,a =
P0 + n0 - 1を得る
解析結果の利用
• 以上の解析によって各手続きとallocation
blocks 毎に、アクセス領域を手続きの引数
を変数とする多項式で表現できる
– RRbaseInc,a = RRbaseInc,a = {[q0, q0 + m0 - 1] }
– RRdcInc,a = RRdcInc,a = {[p0, p0 + n0 - 1] }
– RRmain,a = RRmain,a = {-∞, +∞] }
• コンパイラはこれらを利用して、データの競
合検出などを行う
アルゴリズムの拡張
• 相関解析
– ループ変数と相関して変動する変数については、ルー
プ条件から得られる制約条件を適用できる
• 整数での割り算
– ポインタ演算や分割統治では整数での割り算が行わ
れるので、上限・下限計算のときに配慮が必要
• 制約条件系の分割
– 変数の上限・下限が多項式で表現できない、または
推定できない場合
– 変数の依存関係を抽出し、独立して解けるように問題
を分割する
制約条件系の分割
• 以下の基準を満たすように分割する
– 依存関係にない変数・アクセス領域は別の系に分割
する
– ループ内の制約は別の系に分割する
– 同一の変数に対する上限の制約と下限の制約は分
割する
• 分割により、一般に速く制約を解けるようになる
• またある変数の範囲が定まれば、多項式で表現
できなかった制約を表現できるようになり得る
解析の文脈
• ポインタ解析では各手続きの文脈ごとに、
複数の結果が得られる
– このアルゴリズムも、各文脈ごとに適用する必
要がある
• 同じ文脈の冗長な評価を避けるためGhost
allocation blocks というテクニックが使用さ
れる
– このアルゴリズムもそれに対応するように拡
張できた
実験
• SUIF を使用してコンパイラを実装
• Cilk と C を受け付けて解析する
– Cilk の場合は、データ競合を検出
– C の場合は、自動的に並列化する
– どちらの場合でも、配列の境界チェックを行う
• 実験プログラムは人手で最適化が施され、ポ
インタ演算や動的割り当て、再帰呼び出しが
ふんだんに使用されている
対象プログラム
•
•
•
•
•
•
Fibonacci
QuickSort
MergeSort
Heat(メッシュでの熱拡散)
Knapsack
BlockMul (行列の積、スタック上に一時配列を確
保)
• NoTempMul(同上、ただし一時配列不使用)
• LU
結果(1/3)
• Knapsack プログラム以外は全て、データの競合
がないこと、配列の境界違反がないことを確認で
きた
– Knapsack プログラムは故意にデータ競合する部分が
あった
• 自動並列化
–
–
–
–
Sun Ultra Enterprize (8CPUs)
8,000,000 numbers のソート
1024*1024行列の演算
プロセッサ数に見合った性能が得られた
結果(2/3)
9
8
7
6
5
4
3
2
1
0
1
2
4
6
8
Fib
QS
MS H ea t Mul
N oT
LU
(プロセッサ数による処理速度の変化、論文中のデータより作成)
結果(3/3)
• ビット数の解析
– ポインタの指すメモリ領域でなく、各変数が保
持する値のビット数を求めるようにアルゴリズ
ムを修正
– レジスタのビット数を、またはメモリのビット数を
節約できることを示せた
関連研究(1/4)
• Symbolic Memory Access Region Analysis
– 過去の研究
• 不動点アルゴリズムを使用するため、計算を終える
ために ad hoc な技術が使用された
– 再帰の回数を制限する
– ポインタが指す領域を適宜拡張する
• ループ内の各手続き呼び出しを解析して、ループを
並列化する、というやり方が多い
– 本研究では汎的なフレームワークを提示、プ
ログラムが並列でも逐次でも適用可能にした
関連研究(2/4)
• Array Bounds Check Elimination
– 過去の研究
• チェックをループの外に出す
• ループ終了条件をチェックに応用する
• ループを主な制御構造とする時によくあるような、単純な条
件チェックが中心
– 本研究は再帰するプログラムを対象とする
• 配列やポインタが利用される時点だけでなく、手続きを呼び
出す時点でもチェックができる
• 配列チェックをしない言語にも適用できる
• アクセス領域を多項式で表記したのがポイント
関連研究(3/4)
• Race Detection
– 過去の研究
• 並列スレッドのアクセスを動的に記録して、競合の検出に利
用する
– 排他制御やSignal/wait を使用してデータ競合を防ぐ試み
• Lock を正しく取得してからアクセスするようにプログラマに明
示的に宣言させる
– 本研究と正対する立場
• 本アルゴリズムでは、複数のスレッドが完全に別々の領域に
アクセスすることを保証している
関連研究(4/4)
• Parallelizing Compiler
– 過去の研究はループ中の配列へのアクセスを
並列化することに焦点
– 本研究は再帰、動的確保、ポインタ演算をする
ようなプログラムに適用可能
– 「逐次処理の自動並列化と並列処理のデータ
競合検出を同列に扱えるようにした」
– ほかにShape analysis や、Commutativity
analysis といった技法もある
主なReference
•
•
•
•
R. Rugina and M. Rinard. Pointer analysis for multithreaded programs. In
Proceedings of the SIGPLAN '99 Conference on Program Language Design
and Implementation, Atlanta, GA, May 1999.
F. Gustavson. Recursion leads to automatic variable blocking for dense linearalgebra algorithms. IBM Journal of Research and Development, 41(6):737-755,
November 1997.
J. Frens and D. Wise. Auto-blocking matrix-multiplication or tracking BLAS3
performance from source code. In Proceedings of the 6th ACM SIGPLAN
Symposium on Principles and Practice of Parallel Programming, Las Vegas,
NV, June 1997.
S. Chatterjee, A. Lebeck, P. Patnala, and M. Thottethodi. Recursive array
layouts and fast matrix multiplication. In Proceedings of the 11th Annual ACM
Symposium on Parallel Algorithms and Architectures, Saint Malo, France,
June 1999.