<2008/11/28記>
P0〜P5領域のキャッシュの効き目を実際に確認してみた。
リンカのセクション指定と変数のマッピングの関係が分かってないとこんがらがるな。
ま、ポインタで直接やりゃぁ簡単だ。セクション指定なんぞ関係なくなるもんよ。、
ところでXYメモリーは特別にキャッシュが効くのだ。
P2領域からのアクセスでもキャッシュが効くのだ。ちゅうか取説を良く読んだら「キャッシュ有効にしてP2(Lバス)からアクセスしろ。キャッシュ有効のままでP0(Iバス)からアクセスしたら、どうなっても知らんへんで」と書いてあったわ。HARD取説 P225
// キャッシュON void Oj3_CashOn(void) { wrl(CCR1,rdl(CCR1) | BIT00); } // キャッシュOFF void Oj3_CashOff(void) { wrl(CCR1,rdl(CCR1) & ~BIT00); } // ↓これは外部変数。こいつはBセクション内にある。外付けのSDRAMね。 // Bセクションを0C00_0000(P0領域)にマッピングしたのでキャッシュが有効である。 char g_buff[0x100000]; void GRg_main(void) { Oj3_CashOn(); // Cashオン時 0.14秒 //Oj3_CashOff(); // Cashオフ時 5秒 for (i=0x0;i<0x100000;++i) g_buff[i]=0xaa; // 以下の方法ならセクション指定と無関係にキャッシュの効きを確認可能だ Oj3_CashOn(); // Cashオン p=(uchar*)0x0C000000; // P0領域からアクセス..キャッシュが効く<7秒 p=(uchar*)0xAC000000; // P2領域からアクセス..キャッシュが効かない<27秒 for (i=0x0C000000;i<=0x0FFFFFFF;++i) *p++=0x55; |
XYメモリーは速度が速いんで、上手く使うととても結構なり。
XとYに各8kバイトずつと少ないけど、非常に早いと言うのはエエですな。
なおP2領域からアクセスすること。P2からのアクセスだけど特別扱いでキャッシュが有効なのだ。キャッシュ参照
ポインタでアクセスする場合はDSPレジスタを使わないけど、shc専用のXYメモリー定義方式ではDSPレジスタを使うんで、忘れずに特権DSPモードに入ること。
んま、XYメモリーを使うときは黙って特権DSPモードでやることじゃ。ソース
XYメモリーへのアクセス例 p=(uchar*)0xA5007000; // Xメモリー p=(uchar*)0xA5017000; // Yメモリー Oj3_CashOn(); // Cashオン<0.0005秒 //Oj3_CashOff(); // Cashオフ<0.18秒 for (i=0x7000;i<0x8fffu;++i) *p++=0x55; // shc専用のXYメモリー定義方式の場合 float __X x1; // X に格納 float __Y y1; // Y に格納 void Oj3_CashTest3(void) { Oj3_SetSrDsp(); // 特権DSPモードに入る。 x1=0.5; // x1は$XBセクションに自動的に配置される y1=0.5; // y1は$YB " } |
<2008/11/28記>
これがまた分からん。
どうしても例外エラーが出て途中で止まっちゃう。
何が悪いのか、何が悪いのか・・メモリーアクセスかCPUモードか・・
は〜〜アセンブラのソースを見てたら分かったなり〜
固定小数点の演算ライブラリが内部でDSPレジスタを使ってるじゃん!
grg.c (121): for (i=0; i<NUM; i++) result[i]=input[i] + 0.125r;
000023C0 Oj3_Fixe..EE00
MOV #0,R14 i
000023C2 Oj3_Fixe..E108
MOV #8,R1
000023C4 Oj3_Fixe..3E13
CMP/GE R1,R14 i
000023C6 Oj3_Fixe..8914
BT 000023F2
000023C8 Oj3_Fixe..D423
MOV.L 00002458,R4
これ → 000023CA Oj3_Fixe..44BA LDS R4,Y1
000023CC Oj3_Fixe..D623
MOV.L 0000245C,R6
000023CE Oj3_Fixe..62E3
MOV R14 i ,R2
ここで「LDS R4,Y1」がDSPレジスタへのアクセス命令で、「LDS Rn,Y1」はRn → Y1へのデータ転送命令。HARD取説 P150
またDSPレジスタには、A0,A1,X0,X1,Y0,Y1,M0,M1がある。HARD取説 P98
ちゅうことで固定小数点演算は特権DSPモードで行うこと。ソース
しっかしRISCプロセッサのアセンブラコードは見たくないねぇ(^^;
DSP取説 P88 固定小数点の基礎 ここも参照
数値範囲は正確には +0.999..から-1.0 である。
限界値を使うときは #include <fixed.h> してから FIXED_MIN とか FIXED_MAX を使おうね。
注意:__fixed で -1.0r とすると -0.999969 になるんで、本当の -1.0 が必要なときは -0.5r-0.5r と書く・・黙って
FIXED_MIN を使うこっちゃ。
図10 固定小数点の範囲、添字、型変換 | ||||||||||||||||||||
|
16ビットの固定小数点 __fixed のデータ形式って short とまるっきり同じなのな。なかなか気が付かなかった。
でも、__fixed に short を代入したら、まともな値が出てこない。
あれれ?特殊なフォーマットなワケ?とか色々勘ぐっちゃって悩んじゃってDUMPしたりしちゃって・・結局、同じだったのだ。
__fixed と short はコンパイラの解釈が違うってことみたいね。
下のコードで実験したら分かったのだ。
そのまま代入せずに、ポインタを使って無理矢理入れちゃえばOK・・強姦です(^^;
固定小数点の詳細はここのリンクを見るのだ。
// short を代入してみた void Oj3_FixedFloatTest(void) { char ss[50]; short sa,*p; __fixed fa; Oj3_SetSrDsp(); // 特権DSPモードに入る。 sa=0xe000; // -0.25 fa=(__fixed)sa; sprintf(ss,"%r",fa); // ダメ p=(short*)&fa; *p=sa; sprintf(ss,"%r",fa); // OK } |
XYメモリーを使って固定小数点演算をしたのだ。
これはつまり後でFFT演算をするときのための下準備ちゅうか練習だな。
// Xメモリー使用例 __fixed __X xa,xb,xc; void Oj3_FixedFloatTest2(void) { char ss[30]; __fixed q1,q2,q3; float ff,ff2,ff3,ff4; // Xメモリーを使うんで特権DSPモードじゃないと動かないのだ。 Oj3_SetSrDsp(); // fixedのローカル変数はPALMICEでは正常に見えないが結果はOK q1=0.2r; q2=0.3r; q3=q1 * q2; sprintf(ss,"%r",q3); // 即値の場合は結果が範囲内であればOK q1=2.0r / 10.0r; sprintf(ss,"%r",q1); // -1.0rは使えない、-0.5r-0.5rと記述すること q1=-1.0r; sprintf(ss,"%r",q1); // 結果は-0.999969となる q1=-0.5r-0.5r; sprintf(ss,"%r",q1); // 結果は-1.0となる q1=FIXED_MIN; // FIXED_MINが良いよ sprintf(ss,"%r",q1); // 結果は-1.0となる xa=0.2r; xb=0.3r; // 固定と即値のかけ算 xc=0.08 OK xc=xa * 0.4r; sprintf(ss,"%r\n",xc); // 固定同士のかけ算 xc=0.06 OK xc=xa * xb; sprintf(ss,"%r\n",xc); ff2=5.0; ff3=0.5; ff4=3.2; // 浮動 ← 固定 ff=0.06 OK ff=xc; sprintf(ss,"%f\n",ff); // 浮動 ← 固定+即値 ff=5.06 OK ff=xc + 5.0; sprintf(ss,"%f\n",ff); // 浮動 ← 浮動+浮動 ff2=5.56OK ff2=ff + ff3; sprintf(ss,"%f\n",ff2); // 浮動 ← 固定+浮動 ff=3.26 OK ff=ff4 + xc; sprintf(ss,"%f\n",ff); nop(); } |
DSP取説 P93によると「結果が演算範囲を超えると、強制的に最大値(最小値)に置き換えること」と書いてあるな。
早速試してみた。
__fixed a,result; __sat __fixed b; // ↓これはダメ。aかbを__sat修飾しないと飽和演算にならない。 //__fixed a,b; //__sat __fixed result; Oj3_SetSrDsp(); // 特権DSPモードじゃないと動かないよ。 a=0.8r; b=0.5r; result=a+b; // 結果は+1.0(+0.999..)になる a=-0.8r; b=-0.5r; result=a+b; // 結果は-1.0になる |