吉田/覚書/ループアンローリング@第14回ASICデザコンのソートプログラム
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
[[吉田>吉田]]/[[覚書>吉田/覚書]]
#contents
**ループアンローリング@第14回ASICデザコンのソートプログラム [#u9ac7bf6]
* ex() 内で使ってる変数 → lbl1, lbl2, reg, regx, i, tmp, mv_flag
-あまり増やしたくないが再利用も微妙。
* yacc だと、FOR文: FOR '(' astmt ';' expr ';' astmt ')' stmt
***4:変数処理(ループ処理に限った話じゃないけど) [#g718f2c6]
-バックエンド(picob.c)ではレジスタ管理テーブルを用いてレジスタにロードされているのが即値ならその値を、変数ならそのインデックス値をダイレクトに持ってこれる。
--reg_table[](構造体Reginfo)には busy, type, value, i があるが、Aをレジスタ番号としてそれぞれ
---reg_table[A].busy :使用状況。
---reg_table[A].type :ロードされている値の種類。(->type)
---reg_table[A].value :保持する値。上のタイプがConなら即値が、Idなら変数インデックス値が入っている。(->con.value or ->id.i)
---reg_table[A].i :参照履歴。呼ばれた回数が入っていてレジスタが足りなくなったときこの値の少ないものから潰される。
--を表している。
-即値なら値が分かるが変数だとアセンブラ経由でメモリにアクセスしないと値が分からない。
--FORの終了条件(op[1])から実行回数を出そうとして
reg = ex(p->opr.op[1]->opr.op[0]);
regx = ex(p->opr.op[1]->opr.op[1]);
if(p->opr.op[2]->opr.oper == PP)
if(p->opr.op[1]->opr.oper == '<')
if( reg_table[reg].value < reg_table[regx].value )
tmp = reg_table[reg].value - reg_table[regx].value;
とかやっても、少なくともregは変数なので atoi(k)<5 みたいなことになると。
-ノードを辿ったらどうか
if(p->opr.op[1]->opr.oper == '>')
if( p->opr.op[1]->opr.op[0]->... > p->opr.op[1]->opr.op[1]->... )
tmp = p->opr.op[1]->opr.op[1]->... - p->opr.op[1]->opr.op[1]->...;
--やっぱりtypeIdのノードはインデックスしか持ってないから不可。
--むぅ。
(攻略未定)
-何かあったら書く。
#comment
***3:ループ全展開 [#sdebe93d]
-じゃあ2段目だけと言わず全部展開しちゃえばいいんじゃね?
-今回で言うと、sum(19 to 1) = 190で、190回IFを吐けばいい・・・のか?
--ソース肥大化。条件判定、更新処理の分速くはなる、のかも。
--出来ればそんなのやりたくない。
***2:ループ構造の問題 [#w6dfba72]
-for(i=0;i<n-1;i++)for(j=n-1;j>i;j--){}・・・なので、2個目のFORをバラす時に実行処理数の変化に対応させなければならない。
-今回で言えば1段FORで i=0 の時2段FORは19回、1段FORで i=1 の時2段FORは18回、と減らさねばならない。
-ぱっと浮かぶ解決法は各処理の間に条件分岐を置けばいいがそれは今回の改良目標に真っ向否定してくるので却下。
さて。
***1:多重ループ判定をどうするか [#dabe8997]
-yaccじゃメドい → b.c内でFOR時条件分岐
-もし多重ループだったなら(判定はp->opr.op[3]->opr.oper == FOR, とか?)
--p->opr.op[3]->opr.op[0] で初期値
--p->opr.op[3]->opr.op[1] で実行回数決定
--p->opr.op[3]->opr.op[3] から内容実行
---ここの内部変数の値変化をコンパイラでいい感じに。
---実行ごとにp->opr.op[3]->opr.op[2]で更新作業を。
・・・今回でいうと、下図で~
(for) <ここから、
|
| ------------
| | | |
(0) (1) (2) (for)
|
| ------------
| | | |
ここを読んで> (0) (1) (2) (if)
|
| ---
| |
(0) ({ })
|
| -------
| | |
この辺りの式を書き換える、> (0) (1) (2)
・・・えー、~
・・・・・・・・・・・ん。~
p->opr.op[3]->opr.op[0-2]を解釈、お膳立てしてex(p->opr.op[3]->opr.op[3]);実行すればいけるか。
はて。
終了行:
[[吉田>吉田]]/[[覚書>吉田/覚書]]
#contents
**ループアンローリング@第14回ASICデザコンのソートプログラム [#u9ac7bf6]
* ex() 内で使ってる変数 → lbl1, lbl2, reg, regx, i, tmp, mv_flag
-あまり増やしたくないが再利用も微妙。
* yacc だと、FOR文: FOR '(' astmt ';' expr ';' astmt ')' stmt
***4:変数処理(ループ処理に限った話じゃないけど) [#g718f2c6]
-バックエンド(picob.c)ではレジスタ管理テーブルを用いてレジスタにロードされているのが即値ならその値を、変数ならそのインデックス値をダイレクトに持ってこれる。
--reg_table[](構造体Reginfo)には busy, type, value, i があるが、Aをレジスタ番号としてそれぞれ
---reg_table[A].busy :使用状況。
---reg_table[A].type :ロードされている値の種類。(->type)
---reg_table[A].value :保持する値。上のタイプがConなら即値が、Idなら変数インデックス値が入っている。(->con.value or ->id.i)
---reg_table[A].i :参照履歴。呼ばれた回数が入っていてレジスタが足りなくなったときこの値の少ないものから潰される。
--を表している。
-即値なら値が分かるが変数だとアセンブラ経由でメモリにアクセスしないと値が分からない。
--FORの終了条件(op[1])から実行回数を出そうとして
reg = ex(p->opr.op[1]->opr.op[0]);
regx = ex(p->opr.op[1]->opr.op[1]);
if(p->opr.op[2]->opr.oper == PP)
if(p->opr.op[1]->opr.oper == '<')
if( reg_table[reg].value < reg_table[regx].value )
tmp = reg_table[reg].value - reg_table[regx].value;
とかやっても、少なくともregは変数なので atoi(k)<5 みたいなことになると。
-ノードを辿ったらどうか
if(p->opr.op[1]->opr.oper == '>')
if( p->opr.op[1]->opr.op[0]->... > p->opr.op[1]->opr.op[1]->... )
tmp = p->opr.op[1]->opr.op[1]->... - p->opr.op[1]->opr.op[1]->...;
--やっぱりtypeIdのノードはインデックスしか持ってないから不可。
--むぅ。
(攻略未定)
-何かあったら書く。
#comment
***3:ループ全展開 [#sdebe93d]
-じゃあ2段目だけと言わず全部展開しちゃえばいいんじゃね?
-今回で言うと、sum(19 to 1) = 190で、190回IFを吐けばいい・・・のか?
--ソース肥大化。条件判定、更新処理の分速くはなる、のかも。
--出来ればそんなのやりたくない。
***2:ループ構造の問題 [#w6dfba72]
-for(i=0;i<n-1;i++)for(j=n-1;j>i;j--){}・・・なので、2個目のFORをバラす時に実行処理数の変化に対応させなければならない。
-今回で言えば1段FORで i=0 の時2段FORは19回、1段FORで i=1 の時2段FORは18回、と減らさねばならない。
-ぱっと浮かぶ解決法は各処理の間に条件分岐を置けばいいがそれは今回の改良目標に真っ向否定してくるので却下。
さて。
***1:多重ループ判定をどうするか [#dabe8997]
-yaccじゃメドい → b.c内でFOR時条件分岐
-もし多重ループだったなら(判定はp->opr.op[3]->opr.oper == FOR, とか?)
--p->opr.op[3]->opr.op[0] で初期値
--p->opr.op[3]->opr.op[1] で実行回数決定
--p->opr.op[3]->opr.op[3] から内容実行
---ここの内部変数の値変化をコンパイラでいい感じに。
---実行ごとにp->opr.op[3]->opr.op[2]で更新作業を。
・・・今回でいうと、下図で~
(for) <ここから、
|
| ------------
| | | |
(0) (1) (2) (for)
|
| ------------
| | | |
ここを読んで> (0) (1) (2) (if)
|
| ---
| |
(0) ({ })
|
| -------
| | |
この辺りの式を書き換える、> (0) (1) (2)
・・・えー、~
・・・・・・・・・・・ん。~
p->opr.op[3]->opr.op[0-2]を解釈、お膳立てしてex(p->opr.op[3]->opr.op[3]);実行すればいけるか。
はて。
ページ名: