省メモリと動作速度
省メモリと動作速度
今PSPに龍神録を移植しています
やはりクオリティの低いものですが、オリジナルの弾幕も2つほど動作させ、タイトルも作り5回ぴちゅるとゲームオーバーという概念も作ってなんとかゲームらしくまとまりました
ただ、PSPで動作させているためやっぱりFPSが30~40くらいになってしまいます(性格には計っていません、だいたいこんなもんかなって奴です)
ちなみにPSPのスペックはCPUが333MHz、メモリ32MB(うちカーネルが8MBを占有エリアとして確保)です(出典wiki)
メモリに余裕があんまりないため、いろいろ調べているとmallocという関数を見つけました
①あれってポインタを宣言して、freeにはめると、参照先のメモリが全部解放されるっていう考えでいいのでしょうか?
また これと
②これだとやっぱり下のほうがより高速になりますか?
後半なんかPSP関係なくなってきちゃいました^^;
③無駄をいろいろ削ぐテクニックはmallocの他に何がありますか?
よろしくお願いします
やはりクオリティの低いものですが、オリジナルの弾幕も2つほど動作させ、タイトルも作り5回ぴちゅるとゲームオーバーという概念も作ってなんとかゲームらしくまとまりました
ただ、PSPで動作させているためやっぱりFPSが30~40くらいになってしまいます(性格には計っていません、だいたいこんなもんかなって奴です)
ちなみにPSPのスペックはCPUが333MHz、メモリ32MB(うちカーネルが8MBを占有エリアとして確保)です(出典wiki)
メモリに余裕があんまりないため、いろいろ調べているとmallocという関数を見つけました
①あれってポインタを宣言して、freeにはめると、参照先のメモリが全部解放されるっていう考えでいいのでしょうか?
また これと
②これだとやっぱり下のほうがより高速になりますか?
後半なんかPSP関係なくなってきちゃいました^^;
③無駄をいろいろ削ぐテクニックはmallocの他に何がありますか?
よろしくお願いします
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
省メモリにするには色々方法がありますが、まず画像の解像度や色数を減らせば大幅な省メモリになります。
PSP開発環境に詳しくないので、どんな色数のデータが最適なのかを調べてみてください。
あとmallocですがPSP開発環境では使えるのでしょうか?まずそこを確認してください。
それとmallocしてfreeで解放するメモリは必要ないから解放するのであって毎フレーム確保・解放なんて繰り返したら却って遅くなります。
利用できる場面をよく考えてみてください。龍神録には殆ど無いはずです。
ちなみにC++ならnew、deleteを使うようにしてくださいね。
それよりは他の工夫で早くなることも多いです。
特にPSPはパソコンと違い浮動小数点型であるdoubleやsin/cos関数が激烈のに遅いはずなので、そこを工夫したほうが良いでしょう。
「ちく のPSPゲーム移植講座!」
http://www.geocities.jp/z_gundam_tanosi ... Kouza.html
PSP開発環境に詳しくないので、どんな色数のデータが最適なのかを調べてみてください。
あとmallocですがPSP開発環境では使えるのでしょうか?まずそこを確認してください。
それとmallocしてfreeで解放するメモリは必要ないから解放するのであって毎フレーム確保・解放なんて繰り返したら却って遅くなります。
利用できる場面をよく考えてみてください。龍神録には殆ど無いはずです。
ちなみにC++ならnew、deleteを使うようにしてくださいね。
YESです。関数呼び出しは少ない方が早くなりますが、プログラムが読み辛くなるのなら無闇に減らすべきではありません。COFE さんが書きました:②これだとやっぱり下のほうがより高速になりますか?
それよりは他の工夫で早くなることも多いです。
特にPSPはパソコンと違い浮動小数点型であるdoubleやsin/cos関数が激烈のに遅いはずなので、そこを工夫したほうが良いでしょう。
「ちく のPSPゲーム移植講座!」
http://www.geocities.jp/z_gundam_tanosi ... Kouza.html
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
早速の解答ありがとうございます
PSPでもmallocは使えます、使いたかったタイミングはタイトル画面がそこそこ容量を食うデザインだったので
タイトルの画像ロード
↓
タイトルの場面
↓
ゲーム開始時にタイトルの画像をfree
こうやって仕様かなと思ってました、タイトルの画像をゲーム本編で使うことはないので
教えていただいたURLを参考にしようと思います、ありがとうございました
PSPでもmallocは使えます、使いたかったタイミングはタイトル画面がそこそこ容量を食うデザインだったので
タイトルの画像ロード
↓
タイトルの場面
↓
ゲーム開始時にタイトルの画像をfree
こうやって仕様かなと思ってました、タイトルの画像をゲーム本編で使うことはないので
教えていただいたURLを参考にしようと思います、ありがとうございました
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
タイトル画面などの画像の解放はDXLIBポータブルでも同じだと思いますがDeleteGraph()で開放してください。
freeでは開放できませんよ。
freeでは開放できませんよ。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
これは毎回sin/cos関数を呼ぶと遅くなるので、sin/cos関数の結果を一度単位などで360度分の配列にして持っておくことで毎回sin/cos関数を呼ぶことを避けるテクニックです。[補足]実際には90度分のsinテーブルで360度cosまでサポート可能です。COFE さんが書きました:と、すいません
教えていただいたページにテーブル化と書いてあったのですがこれはどういう意味ですか?
過去ログが参考になるでしょう。
「三角関数のテーブル化 • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3&t=6079
「テーブル化について • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3&t=4588
「弾幕計算の高速化 • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3&t=4521
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
ない頭で必死に考えた結果テーブル化とは
#define sin(KAZU) mysin[KAZU];
float mysin[90]={0 , 0.0175 , 0.0349,};
float mycos[90]={1 , 0.9998 , 0,9994 ,};
こういうものだと思ったんですがコレって合ってますか?
あと過去ログの方でdixqさんが「1度づつでは足りない、その10倍は欲しい」と言われていましたが
これっはどういう意味なのでしょうか?
#define sin(KAZU) mysin[KAZU];
float mysin[90]={0 , 0.0175 , 0.0349,};
float mycos[90]={1 , 0.9998 , 0,9994 ,};
こういうものだと思ったんですがコレって合ってますか?
あと過去ログの方でdixqさんが「1度づつでは足りない、その10倍は欲しい」と言われていましたが
これっはどういう意味なのでしょうか?
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
実際にはcosはsinの位相の違う波ですからmysinだけで事足りますよ。
省メモリなら、mycosは略するべきです。
まず、0.1度単位に変換します。
double angle = 0.1 * (double)i;
次にラジアン角に変換します。
double rad = PI * (180.0 / angle);
で
sin(rad);
です。
省メモリなら、mycosは略するべきです。
0.1度づつという意味なら宣言はmysin[901]であってますが、計算が違います。COFE さんが書きました:dixqさんが「その10倍は欲しい」といった理由が分かりました
まず、0.1度単位に変換します。
double angle = 0.1 * (double)i;
次にラジアン角に変換します。
double rad = PI * (180.0 / angle);
で
sin(rad);
です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
確か過去に話題になったなぁと思い検索してみました。
「処理落ちの軽減についてと、発射に時間差のある弾の描画順位について • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3 ... fpu#p38818
言えることは、PSPで高速化するためにはPSPのCPUクセ・PSPハードウェアのクセ・C言語などの総合的な知識が必要です。つまり、パソコンで龍神録を高速化するよりも高度なテクニックが必要になってきます。色々とチャレンジして知識を身に付けてくださいね。
「処理落ちの軽減についてと、発射に時間差のある弾の描画順位について • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3 ... fpu#p38818
言えることは、PSPで高速化するためにはPSPのCPUクセ・PSPハードウェアのクセ・C言語などの総合的な知識が必要です。つまり、パソコンで龍神録を高速化するよりも高度なテクニックが必要になってきます。色々とチャレンジして知識を身に付けてくださいね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
今までラジアンって言うものの意味がよくわかってなかったんですが、もしかしてPIで角度を表す方法ですか?
あと
さっきのソースをこう書けってことですか?(10倍にしてんだから1/10で求めるのは当たり前でしたね)
もう一つ
>実際にはcosはsinの位相の違う波ですからmysinだけで事足りますよ。
>省メモリなら、mycosは略するべきです。
これってどういう事ですか?sinだけでcosも分かっちゃうんですか?
あと
#define sin(KAZU) mysin[KAZU];
float mysin[901]
for(int i=0;i<900;i++){
mysin[i]=sin(180/PI*i*0.1);
}
もう一つ
>実際にはcosはsinの位相の違う波ですからmysinだけで事足りますよ。
>省メモリなら、mycosは略するべきです。
これってどういう事ですか?sinだけでcosも分かっちゃうんですか?
Re: 省メモリと動作速度
手前味噌ですが、参考になりますでしょうか。
三角関数のテーブル化に加えて、浮動小数点数を使わないようにできます。
ゲーム向け固定小数点数ライブラリ:ISLeのビデオゲーム工房
自作プログラムに組み込む用途であれば自由に使っていただいて構いません。
三角関数のテーブル化に加えて、浮動小数点数を使わないようにできます。
ゲーム向け固定小数点数ライブラリ:ISLeのビデオゲーム工房
自作プログラムに組み込む用途であれば自由に使っていただいて構いません。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
ラジアン角=弧度法と言いますが、2*PIが360度と言う意味になります。COFE さんが書きました:今までラジアンって言うものの意味がよくわかってなかったんですが、もしかしてPIで角度を表す方法ですか?
「ラジアン - Wikipedia」
http://ja.wikipedia.org/wiki/%E3%83%A9% ... 2%E3%83%B3
なので、
sin(180/PI*i*0.1);
だと
90度の時にsin(180/PI*900*0.1)となりsin((180*90)/PI)ですから計算が変ですよ。
式を再確認してみてください。
「三角関数のグラフ」COFE さんが書きました:これってどういう事ですか?sinだけでcosも分かっちゃうんですか?
http://www.crossroad.jp/mathnavi/math-i ... urafu.html
これで分かるでしょうか?
cosとsinは同じ波形で、sinから90度ずれているだけです。
なので、cosを90度ずらすとsinの計算でcosの値を求めることが出来ます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
>こうですか?
そうです。
>mycos=mysin+PI/2;//90度=PI/2
それは、配列の添字やら弧度法やらsinの計算後の値やらごっちゃになっています。
それにメモリ節約で、mycosテーブルを無くす話をしていたはずですよ。mycosテーブルを初期化する必要はないんです。
例としてテーブルから値を取り出す関数
float tableSin( float 度数法の角度 )
と言う関数を作ったら と言う関数を作ればmycosテーブル不要ですって話です。
あと最終的には、roxion1377さんやISLe さんの話を理解しないと東方並の弾幕密度の弾幕シューティングは速度的に厳しいかも知れません。
PSPで組んだことがないでの断言はできませんが。
そうです。
>mycos=mysin+PI/2;//90度=PI/2
それは、配列の添字やら弧度法やらsinの計算後の値やらごっちゃになっています。
それにメモリ節約で、mycosテーブルを無くす話をしていたはずですよ。mycosテーブルを初期化する必要はないんです。
例としてテーブルから値を取り出す関数
float tableSin( float 度数法の角度 )
と言う関数を作ったら と言う関数を作ればmycosテーブル不要ですって話です。
あと最終的には、roxion1377さんやISLe さんの話を理解しないと東方並の弾幕密度の弾幕シューティングは速度的に厳しいかも知れません。
PSPで組んだことがないでの断言はできませんが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
基本的にfloatで宣言されているところをfixedに変えるだけで使えるようにはしてあるのですが。COFE さんが書きました:ごめんなさい、レベルが高すぎてわけわかめです
付属サンプルの浮動小数点数版と固定小数点数版を比べてみてください。
Re: 省メモリと動作速度
>softyaさん
本来の目的をすっかり忘れていました
度数法って360度で表すやつですよね?なんでラジアンを使わないんですか?
最終的にこんな感じでまとまったんですけどこれじゃダメですかね?
>あと最終的には、roxion1377さんやISLe さんの話を理解しないと東方並の弾幕密度の弾幕シューティングは速度的に厳しいかも知れません。
大丈夫です。学校の課題とかそういうわけでもないので。
本来の目的をすっかり忘れていました
度数法って360度で表すやつですよね?なんでラジアンを使わないんですか?
//iniでやる処理
float mysin[901]
for(int i=0;i<900;i++){
mysin[i]=sin(PI/180*i*0.1);
}
//sin,cosの代わりに使う関数
tableSin(float kakudo){
return mysin[(int)kakudo];
}
tableCos(float kakudo){
return mysin(kakudo+PI/2);
}
>あと最終的には、roxion1377さんやISLe さんの話を理解しないと東方並の弾幕密度の弾幕シューティングは速度的に厳しいかも知れません。
大丈夫です。学校の課題とかそういうわけでもないので。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
>度数法って360度で表すやつですよね?なんでラジアンを使わないんですか?
私のは参考に書いただけなのでラジアン角にしても全然かまいませんよ。
>return mysin[(int)kakudo];
聞く前に試されましたか?
(1)kakudoは度数法角度でしょうか?それともラジアン角?
(2)添字が0~900の範囲で0度から90度の設計になっているので、そこから外れるとエラーです。過去ログを再確認を。-720や1080度が入力されても大丈夫なように補正の計算が必要です。
(3)mysin(kakudo+PI/2);を見る限りラジアン角なんですか? でも、小数点の値で配列はアクセス出来ませんよ。cos(90度)の値は0が返りますか?
良く考えて、まず自分で動かしてみてください。
そして関数をいかにテストするかテスト法を考えて、テストのためのソースコードも一緒に考えましょう。
ここで聞く前に試したほうが試す前に聞くよりも問題点を自分で確認してから聞いたほうが、より深く学ぶことが出来ます。
ぜひ、実践してみてください。
私のは参考に書いただけなのでラジアン角にしても全然かまいませんよ。
>return mysin[(int)kakudo];
聞く前に試されましたか?
(1)kakudoは度数法角度でしょうか?それともラジアン角?
(2)添字が0~900の範囲で0度から90度の設計になっているので、そこから外れるとエラーです。過去ログを再確認を。-720や1080度が入力されても大丈夫なように補正の計算が必要です。
(3)mysin(kakudo+PI/2);を見る限りラジアン角なんですか? でも、小数点の値で配列はアクセス出来ませんよ。cos(90度)の値は0が返りますか?
良く考えて、まず自分で動かしてみてください。
そして関数をいかにテストするかテスト法を考えて、テストのためのソースコードも一緒に考えましょう。
ここで聞く前に試したほうが試す前に聞くよりも問題点を自分で確認してから聞いたほうが、より深く学ぶことが出来ます。
ぜひ、実践してみてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
すいません、こんな人間で
sin,cos自体もよく理解できていないようです
その上に弧度法も混ざってくるからややこしくて……
過去ログから拾ってきたものを改造しました
どう見ても弧度法の角度を渡さにゃならん関数ですよね(関数じゃないけど)
これをどうにかラジアン角に対応させたいんですがどうしましょう
#define sin(KAKUDO) (mysin[(int)(KAKUDO % PI/180)])
#define cos(KAKUDO) (mysin[(int)((KAKUDO + 90) % PI/180)])
こうやってしたら角度がPI(3.141592)の時には弧度法で180度の配列が呼ばれていいかんじだと思うんですが
蛇足になりますが今visual C++2008がしょっちゅうフリーズします
visual C++2010はだいぶ前からフリーズ続きです
Borland C++ compilerはlink32.exeが実行できないと言われます
学習用C言語開発環境(EasyIDEC)は表面的にはコンパイルに成功しているもののexeを走らせると起動できません
cygwinをインストールしていますが時間が死ぬほどかかっています、windows用のGCCは何故かダウンロードに失敗します
PSPSDKはちゃんとビルド出来ますが、PSPが今行方不明です
今visual C++2008をインストールしなおしています
それとさっきからしきりに90度の時のことを~と言われるのは何故ですか?
90度の時はなんかマズイことでもあるんでしょうか?
sin,cos自体もよく理解できていないようです
その上に弧度法も混ざってくるからややこしくて……
過去ログから拾ってきたものを改造しました
#define sin(KAKUDO) (mysin[KAKUDO % 360])
#define cos(KAKUDO) (mysin[(KAKUDO + 90) % 360])
float mysin[360];
for(int i = 0;i < 360;++i) {
mysin[i] = sin(i * PI / 180);
}
これをどうにかラジアン角に対応させたいんですがどうしましょう
#define sin(KAKUDO) (mysin[(int)(KAKUDO % PI/180)])
#define cos(KAKUDO) (mysin[(int)((KAKUDO + 90) % PI/180)])
こうやってしたら角度がPI(3.141592)の時には弧度法で180度の配列が呼ばれていいかんじだと思うんですが
蛇足になりますが今visual C++2008がしょっちゅうフリーズします
visual C++2010はだいぶ前からフリーズ続きです
Borland C++ compilerはlink32.exeが実行できないと言われます
学習用C言語開発環境(EasyIDEC)は表面的にはコンパイルに成功しているもののexeを走らせると起動できません
cygwinをインストールしていますが時間が死ぬほどかかっています、windows用のGCCは何故かダウンロードに失敗します
PSPSDKはちゃんとビルド出来ますが、PSPが今行方不明です
今visual C++2008をインストールしなおしています
それとさっきからしきりに90度の時のことを~と言われるのは何故ですか?
90度の時はなんかマズイことでもあるんでしょうか?
Re: 省メモリと動作速度
#define sin(KAKUDO) (mysin[KAKUDO % 360])
KAKUDOが負の数の場合%の動作はどうでしたっけ.
負の数の時は正の数に直さなければまずかった記憶があります
KAKUDOもintにキャストしてあげたほうがいいと思います
書き忘れてましたがfastmath.hをインクルードしてある程度高速なsinfやcosfを使ってもいいと思いますよ
(sin,cosを考えるよりもループの回数を気にしたり,計算以外の処理を減らすことを考えたほうがいい気もする.
>cygwinをインストールしていますが時間が死ぬほどかかっています
psptoolchainはps2dev?が落ちてるので海外のフォーラムで拾うしか無いですね
KAKUDOが負の数の場合%の動作はどうでしたっけ.
負の数の時は正の数に直さなければまずかった記憶があります
KAKUDOもintにキャストしてあげたほうがいいと思います
書き忘れてましたがfastmath.hをインクルードしてある程度高速なsinfやcosfを使ってもいいと思いますよ
(sin,cosを考えるよりもループの回数を気にしたり,計算以外の処理を減らすことを考えたほうがいい気もする.
>cygwinをインストールしていますが時間が死ぬほどかかっています
psptoolchainはps2dev?が落ちてるので海外のフォーラムで拾うしか無いですね
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
元のmysin=sin(PI/180*i*0.1);でテーブル代入している値を確認してみてください。90度以降の値はありますか?COFE さんが書きました:それとさっきからしきりに90度の時のことを~と言われるのは何故ですか?
90度の時はなんかマズイことでもあるんでしょうか?
新しいfloat mysin[360]; は有るみたいですが、実際には90度までの値を上手く使うことで360度分の値を作る事とが出来ます。
これもsin波形の特性をうまく使った省メモリです。過去ログで90度までのテーブルにする話があったので、そういう設計で行くのかと思ってました。
それと0.1度単位ではなくなってますよ。
COFE さんが書きました: #define sin(KAKUDO) (mysin[(int)(KAKUDO % PI/180)])
#define cos(KAKUDO) (mysin[(int)((KAKUDO + 90) % PI/180)])
%で計算できる余りの計算は整数のみです。浮動小数点が混合された計算で使ってはいけません。
それと整数⇔浮動小数点の変換は結構負荷がでかいので高速化を図るなら避けるべき行為です。
なにか計算で浮動小数点と整数の変換を暗黙変換に任せっぱなし感がありますので、きっちり明示的にキャストして書いてみてください。
それと名前はsinで関数名とかぶるのでNGです。
過去ログの内容をよく見て理解してみてくださいね。今言った話題は必ず出ているはずです。
[追記]
COFE さんが書きました: 蛇足になりますが今visual C++2008がしょっちゅうフリーズします
visual C++2010はだいぶ前からフリーズ続きです
Borland C++ compilerはlink32.exeが実行できないと言われます
学習用C言語開発環境(EasyIDEC)は表面的にはコンパイルに成功しているもののexeを走らせると起動できません
cygwinをインストールしていますが時間が死ぬほどかかっています、windows用のGCCは何故かダウンロードに失敗します
PSPSDKはちゃんとビルド出来ますが、PSPが今行方不明です
なんかOSと言うかレジストリや環境変数等がやばそうな感じですね。
数年同じOSを使っているならOSを再インストールしたほうが良いかも知れません。
あるいはメモリに不良がある可能性もありますが。
コンパイラ以外のソフトでも不具合がでるならメモリを疑ってもよいでしょう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
私はどうすればいいのでしょうか?
アレはダメこれはダメ、softyaさんはきっと私のことを考えて私のためになるように導いてくれているのだと思いますが、私の目的はそれではありません
私のやりたいことは
「sin cos関数で呼び出している値を現在のソースに手を加えること無くテーブル化で高速化したい」
ただこれだけです
例えばsin(PI)と呼び出されているものには……
今いいこと思いつきました さあ、今度こそどうでしょう?
アレはダメこれはダメ、softyaさんはきっと私のことを考えて私のためになるように導いてくれているのだと思いますが、私の目的はそれではありません
私のやりたいことは
「sin cos関数で呼び出している値を現在のソースに手を加えること無くテーブル化で高速化したい」
ただこれだけです
例えばsin(PI)と呼び出されているものには……
今いいこと思いつきました さあ、今度こそどうでしょう?
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
最終的に省メモリと高速化を実現したいんだと思ってましたが違うのでしょうか?COFE さんが書きました:アレはダメこれはダメ、softyaさんはきっと私のことを考えて私のためになるように導いてくれているのだと思いますが、私の目的はそれではありません
私のやりたいことは
「sin cos関数で呼び出している値を現在のソースに手を加えること無くテーブル化で高速化したい」
ただこれだけです
あと、何度か説明したように元の龍神録のint/float/doubleなど混合されたコードのままでは全体的な高速化は難しいと思います。
今回は、とりあえず全体的な高速化は置いておいて部分的なsin/cosの高速化を行うのを主目的とすると言うことでよろしいですか?
で、混乱しているようですので、まずちゃんと設計しましょう。
(1)sin/cosの引数はラジアン角でfloat値である。戻り値も同様にfloatである。
(2)テーブルの分解能は1/2*PI(90度)の1/900単位である。→変えても良いですよ。
(3)テーブルはメモリ節約のため0~1/2*PIの範囲の値しか持たない。他の角度はテーブルを使って計算で求める。
(4)-10*PIやら+20*PIやら0~2*PI(360度)の範囲外のラジアン角にも対応している。
(5)sin/cosの関数名は本来のものと多重宣言になるので別のものに置き換える。
これらの中で(3)とか自分的に難しいと感じたら除外して良いです。
16KB→4KBほどの差ですからね。
最後に、私はCFW対応のPSPを持っていないので導くことしか出来ません。動作検証するのは、COFEさんですからね。
なのでCOFEさんがちゃんと理解していないと速度の検査やバグなど動作検証もできないわけですし、ボトルネックを捜す方法や改善方法も自分で検討しないといけないわけです。
なので慌てず自分の出来る範囲で少しづつ進めて行ってください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
優しく諭していただきありがとうございます
もう省メモリとかどっか行っちゃいましたが、意地でもテーブル化は完成させたいです
とりあえず
(1)sin/cosの引数はラジアン角でfloat値である。戻り値も同様にfloatである。
>眠気のノリで作った奴はだめということですね
(2)テーブルの分解能は1/2*PI(90度)の1/900単位である。→変えても良いですよ。
>まずは90度の範囲でくろうと思います
(3)テーブルはメモリ節約のため0~1/2*PIの範囲の値しか持たない。他の角度はテーブルを使って計算で求める。
>多分理解
(4)-10*PIやら+20*PIやら0~2*PI(360度)の範囲外のラジアン角にも対応している。
>returnの前に何かしらの判定をおけばいい?
(5)sin/cosの関数名は本来のものと多重宣言になるので別のものに置き換える。
>Sinにします
とりあえずsinの場合のみの関数をつくってみたのですが、値の返し方がこれであっているのかわかりません
ラジアンを弧度法に変換する関数も確かmath.hにありましたが、これを使ったら本末転倒ですよね
もう省メモリとかどっか行っちゃいましたが、意地でもテーブル化は完成させたいです
とりあえず
(1)sin/cosの引数はラジアン角でfloat値である。戻り値も同様にfloatである。
>眠気のノリで作った奴はだめということですね
(2)テーブルの分解能は1/2*PI(90度)の1/900単位である。→変えても良いですよ。
>まずは90度の範囲でくろうと思います
(3)テーブルはメモリ節約のため0~1/2*PIの範囲の値しか持たない。他の角度はテーブルを使って計算で求める。
>多分理解
(4)-10*PIやら+20*PIやら0~2*PI(360度)の範囲外のラジアン角にも対応している。
>returnの前に何かしらの判定をおけばいい?
(5)sin/cosの関数名は本来のものと多重宣言になるので別のものに置き換える。
>Sinにします
float mysin[91]
for(int i=0;i<90;i++){
mysin[i]=sin(PI/90*i);
}
float Sin(float rad){
while(1){
if(rad>PI && rad<=2PI){
rad=rad-PI;
return mysin[PI/2/rad];
}
else if(rad>2PI){
rad=rad-PI;
}
}
}
ラジアンを弧度法に変換する関数も確かmath.hにありましたが、これを使ったら本末転倒ですよね
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
それではテーマをsin/cosのテーブル化に絞ります。
ラジアン角の変換が間違っています。
(1/2)*PIが90度です。
sin波形の解釈に間違いがあります。下記サイトのグラフを見てください。
http://www8.plala.or.jp/ap2/suugaku/san ... html#graph
テーブルは90度までしか無いので波形はπ/2までのデータしか参照できません。
なので91度から180度、181度から270度、271度から360度はテーブルを元に別々の値を計算しなくてはいけません。
ややこしいので、とりあえずラジアン角→度数変換します。
int kakudo = (int)(rad * 180.0 / PI);
このkakudo が0から360度の範囲になるように補正します(後述)。
でとりあえず、91度から180度からの範囲の例を示します。 と書くと実は間違いです。
正しくは、 となります。波形をよく見て考えてみてください。
で、0~360度の範囲に収める方法ですが、whileループしたら高速化の意味がありません。計算しましょう。
if( kakudo > 360 ) kakudo = kakudo % 360;
if( kakudo < 0 ) さて、どう計算しますか?考えてみてください。
[追記]
ついでにテスト環境をDXライブラリとVC++で作ってみましょうか。
参考サイトのグラフのように-360度から720度までDrawPixelでsin波をプロットしてみてください。
まずは普通のsin関数で色は白、自作sin関数の色は赤でプロットします。
これでずれていたら一発でわかります。
ラジアン角の変換が間違っています。
(1/2)*PIが90度です。
sin波形の解釈に間違いがあります。下記サイトのグラフを見てください。
http://www8.plala.or.jp/ap2/suugaku/san ... html#graph
テーブルは90度までしか無いので波形はπ/2までのデータしか参照できません。
なので91度から180度、181度から270度、271度から360度はテーブルを元に別々の値を計算しなくてはいけません。
ややこしいので、とりあえずラジアン角→度数変換します。
int kakudo = (int)(rad * 180.0 / PI);
このkakudo が0から360度の範囲になるように補正します(後述)。
でとりあえず、91度から180度からの範囲の例を示します。 と書くと実は間違いです。
正しくは、 となります。波形をよく見て考えてみてください。
で、0~360度の範囲に収める方法ですが、whileループしたら高速化の意味がありません。計算しましょう。
if( kakudo > 360 ) kakudo = kakudo % 360;
if( kakudo < 0 ) さて、どう計算しますか?考えてみてください。
[追記]
ついでにテスト環境をDXライブラリとVC++で作ってみましょうか。
参考サイトのグラフのように-360度から720度までDrawPixelでsin波をプロットしてみてください。
まずは普通のsin関数で色は白、自作sin関数の色は赤でプロットします。
これでずれていたら一発でわかります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
慌てないでください。Sin関数の引数がラジアン角であれば良いのでSin関数の内部は、どう扱っても良いと言うのを理解しておいてください。
本当にラジアン角のままSin関数の内部まで処理することは便利なのでしょうか?
Sin関数の内部では配列が度数法で格納されているので、どちらにしろテーブルのアクセスはint型の度数法で行う必要があります。どうせ度数法にするのならPSPで高速なint型を多用しようと考えたので、まっさきにint型の度数法に変換する処理を書かせてもらいました。
あとrad=rad%(PI/2);は整数と浮動小数点の理解が怪しいです。%は整数演算ですので思った答えが得られませんよ。このトピック内で何度も整数と浮動小数点を混ぜてはいけないと書いてますが、信じられないなら実際にテストプログラムを書いて試してみてください。
それと私の提案したDrawPixel()のテストプログラムを作れば簡単に確認できますので、ご自分で作った関数が上手く作れているか実際に確認を行ってください。
このプログラムは動作テストしたとは思えません。
DrawPixel()のテストプログラムで、そんなに難しい提案をしたつもりはありませんが分からないことがあったら聞いてください。
ちなみに弧度法とラジアンは同じ意味ですよ。
[補足]
私はCOFEさんに自分で理解してプログラム組んで欲しいのです。
パソコンに比べて貧弱なハードであるPSPで組むというのは、それはそれは大変な事なので一歩一歩理解して進むしか有りません。
苦労して覚えたことは、応用力にもなります。がんばってください。
本当にラジアン角のままSin関数の内部まで処理することは便利なのでしょうか?
Sin関数の内部では配列が度数法で格納されているので、どちらにしろテーブルのアクセスはint型の度数法で行う必要があります。どうせ度数法にするのならPSPで高速なint型を多用しようと考えたので、まっさきにint型の度数法に変換する処理を書かせてもらいました。
あとrad=rad%(PI/2);は整数と浮動小数点の理解が怪しいです。%は整数演算ですので思った答えが得られませんよ。このトピック内で何度も整数と浮動小数点を混ぜてはいけないと書いてますが、信じられないなら実際にテストプログラムを書いて試してみてください。
それと私の提案したDrawPixel()のテストプログラムを作れば簡単に確認できますので、ご自分で作った関数が上手く作れているか実際に確認を行ってください。
このプログラムは動作テストしたとは思えません。
float mysin[91]
for(int i=0;i<90;i++){
mysin[i]=sin(PI/90*i);
}
float Sin(float rad){
int a=-1;
if(rad<0) rad=rad*a;
if(rad>PI && rad<=2PI){
rad=rad%(PI/2);
return mysin[PI/2/rad];
}
}
ちなみに弧度法とラジアンは同じ意味ですよ。
[補足]
私はCOFEさんに自分で理解してプログラム組んで欲しいのです。
パソコンに比べて貧弱なハードであるPSPで組むというのは、それはそれは大変な事なので一歩一歩理解して進むしか有りません。
苦労して覚えたことは、応用力にもなります。がんばってください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
すいません、%の決まりはすっかり忘れていました
それとDXライブラリを使わないで試す方法はありませんか?
今パソコンが調子悪いので知り合いに見てもらっているところです
しばらく帰ってこない予定なのであんまりスペックの良くないパソコンで今書いています
プロンプトに出すやつでsin,cosとかは……無理ですよね
あと私が自作のSin関数の引数をラジアンでやりたいとこだわる理由は、ソースコードに手を加えたくないからです
今でも理解力はありませんが、龍神録の館で弾を飛ばすのにsin,cosを使っていたので三角関数を必死に勉強しました
sinθだのcosθだのいみわからない用語はありましたが、一応龍神録の玉を飛ばす部分が理解できるようになりました
ご指摘の通り用語についても詳しく一から学んだわけではないので曖昧です
ただでさえ今でも頭でグチャグチャになっている360度=2PIがよりややこしくなって訳分からんくなりそうで怖いです
ここから自作の龍神録モドキのsin,cosを私が書き直すと間違いなく100%バグが出ます
どうにか現在のソースコードのsin()の部分をSin()に置き換えるだけで処理が高速に成るようにしたいと甘いこと考えてます
何とかなりませんでしょうか?
とここまで書きましたが、よくよくsoftyaさんの意見を見直すとPSPではint型のほうが計算が早いのですね
だったら昨日思いついた
これを改良してくのはsoftyaさん的にはダメですかね?
なんでもキャッシュが120MBになると昨日ISLeさんに教えてもらったのですが
配列を1/10にしたらこれでもいいですかね?
ちなみにBorland C++ compilerを今使ってるパソコンにインストールしてるところです
それとDXライブラリを使わないで試す方法はありませんか?
今パソコンが調子悪いので知り合いに見てもらっているところです
しばらく帰ってこない予定なのであんまりスペックの良くないパソコンで今書いています
プロンプトに出すやつでsin,cosとかは……無理ですよね
あと私が自作のSin関数の引数をラジアンでやりたいとこだわる理由は、ソースコードに手を加えたくないからです
今でも理解力はありませんが、龍神録の館で弾を飛ばすのにsin,cosを使っていたので三角関数を必死に勉強しました
sinθだのcosθだのいみわからない用語はありましたが、一応龍神録の玉を飛ばす部分が理解できるようになりました
ご指摘の通り用語についても詳しく一から学んだわけではないので曖昧です
ただでさえ今でも頭でグチャグチャになっている360度=2PIがよりややこしくなって訳分からんくなりそうで怖いです
ここから自作の龍神録モドキのsin,cosを私が書き直すと間違いなく100%バグが出ます
どうにか現在のソースコードのsin()の部分をSin()に置き換えるだけで処理が高速に成るようにしたいと甘いこと考えてます
何とかなりませんでしょうか?
とここまで書きましたが、よくよくsoftyaさんの意見を見直すとPSPではint型のほうが計算が早いのですね
だったら昨日思いついた
mysin[31411593];
for(int i=0;i<31411592;i++){
mysin[i]=sin(i/10000000);
}
Sin(float kakudo){
return mysin[kakudo*10000000]
}
なんでもキャッシュが120MBになると昨日ISLeさんに教えてもらったのですが
配列を1/10にしたらこれでもいいですかね?
ちなみにBorland C++ compilerを今使ってるパソコンにインストールしてるところです
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
コマンドプロンプトでも数値でなら確認できますよ。sin計算の値とSinの値を並べてみれば正しいかは検証出来ますよね。COFE さんが書きました:すいません、%の決まりはすっかり忘れていました
それとDXライブラリを使わないで試す方法はありませんか?
今パソコンが調子悪いので知り合いに見てもらっているところです
しばらく帰ってこない予定なのであんまりスペックの良くないパソコンで今書いています
プロンプトに出すやつでsin,cosとかは……無理ですよね
私の提案したのは外部的にはラジアン角のままですよ。内部を度数法で処理しているだけです。COFE さんが書きました: あと私が自作のSin関数の引数をラジアンでやりたいとこだわる理由は、ソースコードに手を加えたくないからです
今でも理解力はありませんが、龍神録の館で弾を飛ばすのにsin,cosを使っていたので三角関数を必死に勉強しました
sinθだのcosθだのいみわからない用語はありましたが、一応龍神録の玉を飛ばす部分が理解できるようになりました
ご指摘の通り用語についても詳しく一から学んだわけではないので曖昧です
ただでさえ今でも頭でグチャグチャになっている360度=2PIがよりややこしくなって訳分からんくなりそうで怖いです
ここから自作の龍神録モドキのsin,cosを私が書き直すと間違いなく100%バグが出ます
どうにか現在のソースコードのsin()の部分をSin()に置き換えるだけで処理が高速に成るようにしたいと甘いこと考えてます
何とかなりませんでしょうか?
なのでsin→Sinに置き換えるだけで使えます。
なので、落ち着いて私の説明をよく読み考えてみてください。引数を度数法に変えるとは一言も書いていません。
PSPのアプリ用のメモリって確か24MBぐらいしか無いんですよね?COFE さんが書きました: これを改良してくのはsoftyaさん的にはダメですかね?
なんでもキャッシュが120MBになると昨日ISLeさんに教えてもらったのですが
配列を1/10にしたらこれでもいいですかね?
そのうち120MB/10=12MBもsinだけで使ったらメモリが絶対足らなくなりますよ。
これも何度も書きますが、落ち着いて考えてみてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
No: 16で度数法の話は出てますが、その時にラジアン角が良いとのことだったので、その後はラジアン角で処理する前提で話を書いているはずです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
>sin(i/10000000);
10000000.0にしなきゃまずいですね
PSPで計算するときintとfloatの速度はそんなに変わらなかった気がします
あとテーブル化にこだわる理由は何ででしょう?fastmathがあるのに.
具体的な数値は出せませんがvfpuのほうが高速だった気がします.
http://trac2.assembla.com/oslibmod/brow ... s.c?rev=25
vfpu_sincos(angle,&sin_val,&cos_val);
のように使えば一度にsin,cosが計算できます
10000000.0にしなきゃまずいですね
PSPで計算するときintとfloatの速度はそんなに変わらなかった気がします
あとテーブル化にこだわる理由は何ででしょう?fastmathがあるのに.
具体的な数値は出せませんがvfpuのほうが高速だった気がします.
http://trac2.assembla.com/oslibmod/brow ... s.c?rev=25
vfpu_sincos(angle,&sin_val,&cos_val);
のように使えば一度にsin,cosが計算できます
Re: 省メモリと動作速度
>roxion1377さん
他の方法も教えていただきありがとうございます
VFPUにも興味がありましたのでまた今度試してみます
ですがもう私の頭の中はsinのテーブル化のみです
せっかく教えてもらったのにすいません
もうここはsinテーブル専用トピックということにしといてください
他の方法も教えていただきありがとうございます
VFPUにも興味がありましたのでまた今度試してみます
ですがもう私の頭の中はsinのテーブル化のみです
せっかく教えてもらったのにすいません
もうここはsinテーブル専用トピックということにしといてください
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
調べてみました。
floatとintは同速のようですね。失礼しました。
ただ、float⇔intの型変換は激烈に遅いのでできるだけ避けて、暗黙の型変換を起こさないように細心の注意をはらう必要があります。
ここらへんとか無頓着に暗黙の型変換を使いすぎています。
floatとintは同速のようですね。失礼しました。
ただ、float⇔intの型変換は激烈に遅いのでできるだけ避けて、暗黙の型変換を起こさないように細心の注意をはらう必要があります。
ここらへんとか無頓着に暗黙の型変換を使いすぎています。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
もう本当すいません
プログラミングに興味を持った頃にはcore 2 duoとか出ていた頃で処理が重くて困るとかいうことは今まで無かったもので……
使う型といえばずっとintとdoubleでした
>int a=-1;
>if(rad<0) rad=rad*a;
>ここらへんとか無頓着に暗黙の型変換を使いすぎています。
どうやったら-のデータを+に直せますか?
コレばっかりは上に出して注意された奴しか思いつかないです
プログラミングに興味を持った頃にはcore 2 duoとか出ていた頃で処理が重くて困るとかいうことは今まで無かったもので……
使う型といえばずっとintとdoubleでした
>int a=-1;
>if(rad<0) rad=rad*a;
>ここらへんとか無頓着に暗黙の型変換を使いすぎています。
どうやったら-のデータを+に直せますか?
コレばっかりは上に出して注意された奴しか思いつかないです
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
rad=-rad;COFE さんが書きました:もう本当すいません
プログラミングに興味を持った頃にはcore 2 duoとか出ていた頃で処理が重くて困るとかいうことは今まで無かったもので……
使う型といえばずっとintとdoubleでした
>int a=-1;
>if(rad<0) rad=rad*a;
>ここらへんとか無頓着に暗黙の型変換を使いすぎています。
どうやったら-のデータを+に直せますか?
コレばっかりは上に出して注意された奴しか思いつかないです
ですよ。マイナス単項演算子です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
改めてhttp://www.crossroad.jp/mathnavi/math-ii/sanka ... のサイトを見たところ
まあなんと分かりやすいことでしょう
今まで分からなかった所が綺麗に吹き飛びました
とりあえず私の作りたいものを整理すると
float mysin[91]と宣言する
initで初期化
Sin関数をfloatのラジアンで呼び出し、それをラジアンから度数法の角度に変換する
例えば引数が0.0174524だったときはそれを何とかして1度に変換するです
コレを目指して頑張っています
[追記]
http://detail.chiebukuro.yahoo.co.jp/qa ... q137568028
ここで弧度法と度数法変換する方法書いてありました
ラジアン→度数法の場合は180/πをかけるといいらしいです
コレを踏まえて
と今までのことを踏まえてここまで書きましたが
あきらかにこれsoftyaさんなめきった書き方です、やり直します
とまあこんな感じで自分の日記帳みたいに書いて頭を整理していたわけですが、やっぱりできていないのはfloat←intに変換したくなっちゃうことだと思います
どうあがいてもint=float;こういうコードになっちゃいます
さっきのコードでは多分小数点以下が全部0になると思いますが、その場合でもintの変換は処理が遅いのでしょうか?
まあなんと分かりやすいことでしょう
今まで分からなかった所が綺麗に吹き飛びました
とりあえず私の作りたいものを整理すると
float mysin[91]と宣言する
initで初期化
Sin関数をfloatのラジアンで呼び出し、それをラジアンから度数法の角度に変換する
例えば引数が0.0174524だったときはそれを何とかして1度に変換するです
コレを目指して頑張っています
[追記]
http://detail.chiebukuro.yahoo.co.jp/qa ... q137568028
ここで弧度法と度数法変換する方法書いてありました
ラジアン→度数法の場合は180/πをかけるといいらしいです
コレを踏まえて
#define PI 3.1415926f
float mysin[91];
IniSin();//省略
float Sin(float rad){
int kakudo;
kakudo=rad*180/PI;
if(kakudo<0){
kakudo=-kakudo;
}
if(kakudo>90){
kakudo=kakudo%90;
}
return mysin[kakudo];
}
とまあこんな感じで自分の日記帳みたいに書いて頭を整理していたわけですが、やっぱりできていないのはfloat←intに変換したくなっちゃうことだと思います
どうあがいてもint=float;こういうコードになっちゃいます
さっきのコードでは多分小数点以下が全部0になると思いますが、その場合でもintの変換は処理が遅いのでしょうか?
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
float⇔intの型変換はどうしても遅いので出来るだけ避けてください。
小数以下があろうとなかろうと浮動小数点には関係の無いデータの持ち方をしているので変換時間には関係のないことなのです。
難しい話になりますが、浮動小数点の変数上は整数部を持たず小数以下の値しかありません。桁を表すのは指数部が行います。更に2進法だったりすので更にややこしいのです。
「浮動小数点数 - Wikipedia」
http://ja.wikipedia.org/wiki/%E6%B5%AE% ... 9%E6%95%B0
「浮動小数点数」
http://www.jtw.zaq.ne.jp/kayakaya/new/k ... t/fudo.htm
ややこしいので興味があったら読んでみてください。
後、浮動小数点は徐乗算よりも加減算のほうが遅い特徴があり、浮動小数点演算回路次第では加減算の速度低下には気をつける必要があります。PSPの場合は、速度が落ちるのか必ず確認するようにしてください。
小数以下があろうとなかろうと浮動小数点には関係の無いデータの持ち方をしているので変換時間には関係のないことなのです。
難しい話になりますが、浮動小数点の変数上は整数部を持たず小数以下の値しかありません。桁を表すのは指数部が行います。更に2進法だったりすので更にややこしいのです。
「浮動小数点数 - Wikipedia」
http://ja.wikipedia.org/wiki/%E6%B5%AE% ... 9%E6%95%B0
「浮動小数点数」
http://www.jtw.zaq.ne.jp/kayakaya/new/k ... t/fudo.htm
ややこしいので興味があったら読んでみてください。
後、浮動小数点は徐乗算よりも加減算のほうが遅い特徴があり、浮動小数点演算回路次第では加減算の速度低下には気をつける必要があります。PSPの場合は、速度が落ちるのか必ず確認するようにしてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
http://www.geocities.jp/daichi1969/synt ... .html#osc5
こういうページを見つけました
ここに書いてある
これでfloatを渡すとintになって帰ってくるようなんですが、コレも遅いほうですか?
それ以前に、CPUが違う場合はアセンブリに互換性がなかった気がするのですが、上のコードはPSPで使えますか
あと、出来れば上のアセンブリが何をやっているか教えてもらいたいです
こういうページを見つけました
ここに書いてある
inline int _FLOAT2INT(float f)
{
int i;
__asm__ {
fld dword ptr [f]
fistp dword ptr [i]
}
return i;
}
それ以前に、CPUが違う場合はアセンブリに互換性がなかった気がするのですが、上のコードはPSPで使えますか
あと、出来れば上のアセンブリが何をやっているか教えてもらいたいです
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
x86系(パソコン)CPUのアセンブラですね。COFE さんが書きました:これでfloatを渡すとintになって帰ってくるようなんですが、コレも遅いほうですか?
それ以前に、CPUが違う場合はアセンブリに互換性がなかった気がするのですが、上のコードはPSPで使えますか
あと、出来れば上のアセンブリが何をやっているか教えてもらいたいです
パソコンでは使えますがCPUが違うPSPでは使えません。PSPのCPUは、MIPS R4000 です。
「R4000 - Wikipedia」
http://ja.wikipedia.org/wiki/R4000
まぁ、気合があったら読んでみてください。英語マニュアルです。
MIPS R4000 Microprocessor User's Manual
http://groups.csail.mit.edu/cag/raw/doc ... ok_Ed2.pdf
一応大雑把に説明しておくと
fld dword ptr [f] 浮動小数点レジスタに浮動小数点値をfからロードします。
fistp dword ptr 浮動小数点レジスタの値をintに変換してiにストアします。
もちろんPSPでは使えませんよ。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
MIPS R4000の場合、int→floatの変換は、mtc1とcvt.s.wの2命令が必要です。
逆に、float→intの変換は、trunc.w.sとmfc1の2命令です。
各命令はいずれも数サイクルの命令ですが、同じFPUレジスタを使いまわすので連続で使えなかったはずです。
文脈次第では結構遅くなることがあります。
アセンブリ言語でのコーディングは、よほど熟練していないと高速化できませんので、なるべく避けることをお勧めします。
逆に、float→intの変換は、trunc.w.sとmfc1の2命令です。
各命令はいずれも数サイクルの命令ですが、同じFPUレジスタを使いまわすので連続で使えなかったはずです。
文脈次第では結構遅くなることがあります。
アセンブリ言語でのコーディングは、よほど熟練していないと高速化できませんので、なるべく避けることをお勧めします。
Re: 省メモリと動作速度
色々と考えてみたのですが
引数をfloatで渡す→ラジアンを度数法に変換→テーブルの内容を引っ張る→return mysin[kakudo]
これがしたかったらどう考えてもfloat→intの変換がどこかで必要になってくると思うのですが……
どうしましょう?アイディア尽きてきました
引数をfloatで渡す→ラジアンを度数法に変換→テーブルの内容を引っ張る→return mysin[kakudo]
これがしたかったらどう考えてもfloat→intの変換がどこかで必要になってくると思うのですが……
どうしましょう?アイディア尽きてきました
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
絶対、度数法と言うよりfloat→int型の変換は配列の添字参照で一度は必要ですよ。COFE さんが書きました:色々と考えてみたのですが
引数をfloatで渡す→ラジアンを度数法に変換→テーブルの内容を引っ張る→return mysin[kakudo]
これがしたかったらどう考えてもfloat→intの変換がどこかで必要になってくると思うのですが……
どうしましょう?アイディア尽きてきました
ただ、何度も変換しないように工夫しないといけません。私は一回もするなとは言っていませんので読みなおしてみてください。
そういう意味で、私の提案(Sin関数の引数がラジアン角、Sin関数の内部は度数法に変換して処理)ではダメなのですか?
その理由を教えてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
あ、そうだったんですね
ずっと悩んでました
だったら昨日出したNo40はどうでしょう?
float→intの変換は一回に抑えれてるはずです
ずっと悩んでました
だったら昨日出したNo40はどうでしょう?
float→intの変換は一回に抑えれてるはずです
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
NO.40だと暗黙の型変化ののままなのが気になりますが、一応変換は一回だけのようです。
ただ、コンソールでも良いので動作テストプログラムを組んでみてください。色々と問題があります。
DrawPixelぐらいなら古いパソコンでも耐えるのでDXライブラリでも良いです。
見た目にすごく分りやすいのでDXライブラリをお勧めしますが。
[補足]
問題点は、度数法への変換部分と全く別の部分です。
ただ、コンソールでも良いので動作テストプログラムを組んでみてください。色々と問題があります。
DrawPixelぐらいなら古いパソコンでも耐えるのでDXライブラリでも良いです。
見た目にすごく分りやすいのでDXライブラリをお勧めしますが。
[補足]
問題点は、度数法への変換部分と全く別の部分です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
実行できるパソコンが無いのなら
「codepad」
http://codepad.org/
このWEB上でコンソールアプリなら実行できますよ。
こんな感じで使います。
http://codepad.org/VaFH0WIc
「codepad」
http://codepad.org/
このWEB上でコンソールアプリなら実行できますよ。
こんな感じで使います。
http://codepad.org/VaFH0WIc
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
そのサイト便利ですねー
javascriptとかcgiだけでCコンパイラと同じ挙動示させるなんてすごいですね
とりあえず(父親のパソコンで)作ってみました
コンソールで書けよこんなプログラムってツッコミは置いといてください
http://www.game-create.com/archives/261
ここのサイトの表と比べてみたのですが、明らかに違うんですよね……
調べても変なところは無いし(無いはず無いけど)
どこがダメですか?
javascriptとかcgiだけでCコンパイラと同じ挙動示させるなんてすごいですね
とりあえず(父親のパソコンで)作ってみました
#include <DxLib.h>
#include <math.h>
#define PI 3.1415926f
float mysin[91];
void InitSin(){
int i;
for(i=0;i<90;i++){
mysin[i]=sin(PI/90*i);
}
}
float Sin(float rad){
int kakudo;
kakudo=rad*180/PI;
if(kakudo<0){
kakudo=-kakudo;
}
if(kakudo>90){
kakudo=kakudo%90;
}
return mysin[kakudo];
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
ChangeWindowMode(TRUE);
if(DxLib_Init()==-1) return -1;
InitSin();
for(int i=0;i<90;i++){
printfDx("度数法 %d 度 → Sin %f\n",i,Sin(PI/90*i));
}
ScreenFlip();
WaitKey();
return 0;
}
http://www.game-create.com/archives/261
ここのサイトの表と比べてみたのですが、明らかに違うんですよね……
調べても変なところは無いし(無いはず無いけど)
どこがダメですか?
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
まぁ、色々と変な所があるから、こうなるわけです。
「C++ code - 47 lines - codepad」
http://codepad.org/eABdWOgy
コンソールでも、これだけ表現力があると言う見本をお見せします。
*マークが普通のサイン波で、oマークがCOFEさんのサイン波です。
まず、初期化が怪しいです。その他マイナス処理とか90度を超えた時とか色々と問題があるんです。
なので、cgi自体がコンパイラの働きをしているわけではないですよ。
「C++ code - 47 lines - codepad」
http://codepad.org/eABdWOgy
コンソールでも、これだけ表現力があると言う見本をお見せします。
*マークが普通のサイン波で、oマークがCOFEさんのサイン波です。
まず、初期化が怪しいです。その他マイナス処理とか90度を超えた時とか色々と問題があるんです。
実際にはサーバー側でコンパイラが動いています。COFE さんが書きました:avascriptとかcgiだけでCコンパイラと同じ挙動示させるなんてすごいですね
なので、cgi自体がコンパイラの働きをしているわけではないですよ。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
おお、これは美しい
そして私のsin波(笑)
いやはやとんでもないもの作ってたんですね、お恥ずかしい
もうちょっと研究してきます
そして私のsin波(笑)
いやはやとんでもないもの作ってたんですね、お恥ずかしい
もうちょっと研究してきます
Re: 省メモリと動作速度
#include <DxLib.h>
#include <math.h>
#define PI 3.1415926f
float mysin[91];
void InitSin(){
int i;
for(i=0;i<90;i++){
mysin[i]=sin(PI/180*i);
mysin[i]=mysin[i];
}
}
float Sin(float rad){
int kakudo;
kakudo=rad*(360/(2*PI));
if(kakudo<0){
kakudo=kakudo%90;
kakudo=-kakudo;
}
else if(kakudo>90){
kakudo=kakudo%90;
}
return mysin[kakudo];
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
ChangeWindowMode(TRUE);
if(DxLib_Init()==-1) return -1;
InitSin();
for(int i=0;i<90;i++){
printfDx("%f",mysin[i]);
if(i%5==0 && i!=0) printfDx("\n");
DrawCircle(Sin(PI/90*i)*500,5*i,2,GetColor(255,0,0),TRUE);
DrawCircle(sin(PI/90*i)*500,5*i,2,GetColor(0,0,255),TRUE);
}
ScreenFlip();
WaitKey();
return 0;
}
配列内がちゃんと初期化されているのに失敗するのだからSin関数が怪しいのだろうけど……
日記みたいな書き込みですいません、もうちょっと頑張ってみます
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
分り易くなるようにグラフ風に変えてみました。
あと同じ大きさだと重なって見えないので赤い円のサイズを3にしてあります。
どうですか? 何か法則性のある問題点を感じませんか?
あと同じ大きさだと重なって見えないので赤い円のサイズを3にしてあります。
#include <DxLib.h>
#include <math.h>
#define PI 3.1415926f
float mysin[91];
void InitSin(){
int i;
for(i=0;i<90;i++){
mysin[i]=sin(PI/180*i);
mysin[i]=mysin[i];
}
}
float Sin(float rad){
int kakudo;
kakudo=rad*(360/(2*PI));
if(kakudo<0){
kakudo=kakudo%90;
kakudo=-kakudo;
}
else if(kakudo>90){
kakudo=kakudo%90;
}
return mysin[kakudo];
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
ChangeWindowMode(TRUE);
if(DxLib_Init()==-1) return -1;
InitSin();
int sx,sy,cb;
GetScreenState(&sx,&sy,&cb);
int cy = sy/2;
#define START_KAKUDO (-180) //(-360)
#define END_KAKUDO (360) //(720)
for(int i=START_KAKUDO;i<=END_KAKUDO;i++){
// printfDx("%f",mysin[i]);
// if(i%5==0 && i!=0) printfDx("\n");
int px = (i-START_KAKUDO)*sx/(END_KAKUDO-START_KAKUDO);
DrawCircle(px,Sin(PI/90*i)*(-sy/3)+cy,3,GetColor(255,0,0),TRUE);
DrawCircle(px,sin(PI/90*i)*(-sy/3)+cy,2,GetColor(0,0,255),TRUE);
}
for(int i=START_KAKUDO;i<=END_KAKUDO;i++){
int px = (i-START_KAKUDO)*sx/(END_KAKUDO-START_KAKUDO);
if( (abs(i)%45)==0 ) {
DrawLine(px,0,px,sy,GetColor(255,255,255),TRUE);
DrawFormatString(px+4,cy-20,GetColor(0,255,255),"%d",i);
}
}
DrawLine(0,cy,sx,cy,GetColor(255,255,255),TRUE);
ScreenFlip();
WaitKey();
return 0;
}
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
できました!
コレでいいですかね?
float Sin(float rad){
int kakudo;
int minus=0;
kakudo=rad*(360/(2*PI));
if(kakudo<0) minus=1;
kakudo= minus?-kakudo:kakudo;
if(kakudo % 360 > 180){
kakudo=kakudo%180;
return minus ? mysin[kakudo]: -mysin[kakudo];
}
else{
kakudo=kakudo%180;
return minus ? -mysin[kakudo] : mysin[kakudo];
}
return -1;
}
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
残念ですが、90度から180度を初め何箇所か間違っています。私のプログラムで表示してみてください。
あと、細かい所で問題があるのですがあとで書きます。
[追記]
あと、細かい所で問題があるのですがあとで書きます。
[追記]
float Sin(float rad){
int kakudo;
int minus=0;
kakudo=rad*(360/(2*PI)); 代入時に型が変わっているのでキャストしてくださいね。gccなどコンパイラによっては警告が出来ます。
if(kakudo<0) minus=1; ここを minus = kakudo<0;とした方が良いです。条件計算式の直接代入です。
kakudo= minus?-kakudo:kakudo;
if(kakudo % 360 > 180){ あとの問題はここですね。もっと細かく象限分けをしないとダメですよ。
kakudo=kakudo%180;
return minus ? mysin[kakudo]: -mysin[kakudo];
}
else{
kakudo=kakudo%180;
return minus ? -mysin[kakudo] : mysin[kakudo];
}
return -1;
}
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
おはようございます
昨日やったときは青色のカーブとちゃんと重なってくれたのですがやっぱり手直しが必要なんですね
ここはなんか難しいですよね、昨日もだいぶ悩んでいたところです、もうちょっと研究してきます
一つ質問なんですが ↑これもやはりsoftyaさんに教えてもらったヤツのほうが早いのですか?
昨日やったときは青色のカーブとちゃんと重なってくれたのですがやっぱり手直しが必要なんですね
ここはなんか難しいですよね、昨日もだいぶ悩んでいたところです、もうちょっと研究してきます
一つ質問なんですが ↑これもやはりsoftyaさんに教えてもらったヤツのほうが早いのですか?
- 添付ファイル
-
- 無題.png (46.8 KiB) 閲覧数: 16199 回
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
変ですね・・・。
もしかして、テーブルを90度から180度に増やしませんでしたか?
こちらでは90度から180度、270度から360度の表示はおかしくなりましたよ。
テーブルが90度までしか無いのに180度まで参照しているので当たり前なんですが。
ちなみに、速度を最優先にするなら360度を持っていたほうが良いですけどね。
>これもやはりsoftyaさんに教えてもらったヤツのほうが早いのですか?
明確な速度差があるかは実測してみないと分からないですが、minus = kakudo<0;の方がシンプルですし、真偽値を入れるんだと明確にするならC++なら本当は
bool minus = kakudo<0;
と書いてもらうのが一番良いですです。
もしかして、テーブルを90度から180度に増やしませんでしたか?
こちらでは90度から180度、270度から360度の表示はおかしくなりましたよ。
テーブルが90度までしか無いのに180度まで参照しているので当たり前なんですが。
ちなみに、速度を最優先にするなら360度を持っていたほうが良いですけどね。
>これもやはりsoftyaさんに教えてもらったヤツのほうが早いのですか?
明確な速度差があるかは実測してみないと分からないですが、minus = kakudo<0;の方がシンプルですし、真偽値を入れるんだと明確にするならC++なら本当は
bool minus = kakudo<0;
と書いてもらうのが一番良いですです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
すいません、コードを全部出します
とりあえず、コレをお見せしたかっただけです
>360度持っていたほうが……
これは配列の宣言をmysin[361];にして正負の判断をすっ飛ばす処理にするってことですよね
今から360の場合の方も書いてきます
#include <DxLib.h>
#include <math.h>
#define PI 3.1415926f
float mysin[181];
void InitSin(){
int i;
for(i=0;i<180;i++){
mysin[i]=sin(PI/180*i);
mysin[i]=mysin[i];
}
}
float Sin(float rad){
int kakudo;
int minus=0;//後でboolに
kakudo=rad*(360/(2*PI));
if(kakudo<0) minus=1; //bool minus = kakudo<0;←コレのほうが早い
kakudo= minus?-kakudo:kakudo;
if(kakudo % 360 > 180){
kakudo=kakudo%180;
return minus ? mysin[kakudo]: -mysin[kakudo];
}
else{
kakudo=kakudo%180;
return minus ? -mysin[kakudo] : mysin[kakudo];
}
//ここまで
/*if(kakudo>0){
if(kakudo % 360 > 180){
kakudo=kakudo%180;
return -mysin[kakudo];
}
else{
kakudo=kakudo%180;
return mysin[kakudo];
}
}
else{
kakudo=-kakudo;
if(kakudo % 360 > 180){
kakudo=kakudo%180;
return mysin[kakudo];
}
else{
kakudo=kakudo%180;
return -mysin[kakudo];
}
}*/
return -1;
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
ChangeWindowMode(TRUE);
if(DxLib_Init()==-1) return -1;
InitSin();
int sx,sy,cb;
GetScreenState(&sx,&sy,&cb);
int cy = sy/2;
#define START_KAKUDO (-180) //(-360)
#define END_KAKUDO (360) //(720)
for(int i=START_KAKUDO;i<=END_KAKUDO;i++){
int px = (i-START_KAKUDO)*sx/(END_KAKUDO-START_KAKUDO);
DrawCircle(px,Sin(PI/90*i)*(-sy/3)+cy,3,GetColor(255,0,0),TRUE);
DrawCircle(px,sin(PI/90*i)*(-sy/3)+cy,2,GetColor(0,0,255),TRUE);
}
for(int i=START_KAKUDO;i<=END_KAKUDO;i++){
int px = (i-START_KAKUDO)*sx/(END_KAKUDO-START_KAKUDO);
if( (abs(i)%45)==0 ) {
DrawLine(px,0,px,sy,GetColor(255,255,255),TRUE);
DrawFormatString(px+4,cy-20,GetColor(0,255,255),"%d",i);
}
}
DrawLine(0,cy,sx,cy,GetColor(255,255,255),TRUE);
ScreenFlip();
while(ProcessMessage()!=-1){
WaitKey();
}
return 0;
}
>360度持っていたほうが……
これは配列の宣言をmysin[361];にして正負の判断をすっ飛ばす処理にするってことですよね
今から360の場合の方も書いてきます
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
やっぱりテーブルを180度まで拡張してましたね。
最後に見せてもらったのは90度までのテーブル板でしたよ。
最後に見せてもらったのは90度までのテーブル板でしたよ。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
ありがとうございます、ついに360度の方も完成しました
配列の宣言とInitSinもいじってあります
条件演算子を多用して可読性もなんもないですが一応動きます(笑)
早速PSPの龍神録モドキでこのコード使います
ただ、softyaさんって本当にすごいですね、コードも見ずにどのへんが変えられたか瞬時に判断できるなんて
ちょっと前のところで、私に1から考えて作って欲しいと言われましたよね
私が最初質問してテーブル化を教えてもらったときには、同時にテーブル化のコードも教えてもらえるんじゃないかと甘いこと考えてました
しかし、1から自分で作ってみることによって kakudo = 0<kakudo; ←こういう入門書にちょこっと載っていたけどすっかり忘れていた書き方も分かりましたし、正直ちゃんと習ったわけではないので詳しくなかった三角関数もかなり理解を深めることが出来ました
さっき1から考えたとかいいましたが、このSin関数はsoftyaさんの教えがなければ絶対に完成しなかったものだと思います
途中で逆切れしたりしていろいろご迷惑をおかけしました
Sinテーブルが完成したのはsoftyaさんのお陰です
本当にありがとうございました
float Sin(float rad){
int kakudo = (int)(rad*(360/(2*PI)));
bool minus = kakudo<0;
kakudo = (minus ? -kakudo : kakudo) % 360;
return minus ? -mysin[kakudo] : mysin[kakudo];
}
条件演算子を多用して可読性もなんもないですが一応動きます(笑)
早速PSPの龍神録モドキでこのコード使います
本当に申し訳ありません、見落としていましたsoftya(ソフト屋) さんが書きました:やっぱりテーブルを180度まで拡張してましたね。
最後に見せてもらったのは90度までのテーブル板でしたよ。
ただ、softyaさんって本当にすごいですね、コードも見ずにどのへんが変えられたか瞬時に判断できるなんて
ちょっと前のところで、私に1から考えて作って欲しいと言われましたよね
私が最初質問してテーブル化を教えてもらったときには、同時にテーブル化のコードも教えてもらえるんじゃないかと甘いこと考えてました
しかし、1から自分で作ってみることによって kakudo = 0<kakudo; ←こういう入門書にちょこっと載っていたけどすっかり忘れていた書き方も分かりましたし、正直ちゃんと習ったわけではないので詳しくなかった三角関数もかなり理解を深めることが出来ました
さっき1から考えたとかいいましたが、このSin関数はsoftyaさんの教えがなければ絶対に完成しなかったものだと思います
途中で逆切れしたりしていろいろご迷惑をおかけしました
Sinテーブルが完成したのはsoftyaさんのお陰です
本当にありがとうございました
最後に編集したユーザー COFE on 2011年8月09日(火) 12:13 [ 編集 1 回目 ]
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
おめでとうございます。
ただ、cosと0.1版が完成していないですが良いんでしょうか?
それと実際のアセンブラコードを見てみないと分かりませんが、分岐が多いかも知れません=遅い。
MIPS R4000などのCPUでは極力分岐を減らすことが高速化に繋がりますので、工夫したほうが良いかも知れません。
なので、最初に一回だけif文で分岐するだけの方が高速かも。
ただ、cosと0.1版が完成していないですが良いんでしょうか?
それと実際のアセンブラコードを見てみないと分かりませんが、分岐が多いかも知れません=遅い。
MIPS R4000などのCPUでは極力分岐を減らすことが高速化に繋がりますので、工夫したほうが良いかも知れません。
なので、最初に一回だけif文で分岐するだけの方が高速かも。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
cosのことすっかり忘れてました
前にcosについてもちょっと言われた気がするのでまた過去ログ漁ってきます
cos出来るまで解決タグまた外しますね
前にcosについてもちょっと言われた気がするのでまた過去ログ漁ってきます
cos出来るまで解決タグまた外しますね
Re: 省メモリと動作速度
できました(多分……)
0.5*(PI/180)を渡したところ0.008727が帰ってきましたのでたぶん大丈夫です
Cosは前にsoftyaさんに教えてもらったののそのままパクりですw
この部分は「やっヴぇwww俺かっこいいwww」って感じでお気に入りの箇所だったんですが、実行速度には変えられないので元に戻します
これでsinテーブル(度数法で小数第一位まで)+cos完成と考えていいですか?
float mysin[3601];
void InitSin(){
int i;
for(i=0;i<3600;i++){
mysin[i]=sin((PI/(1800))*i);
mysin[i]=mysin[i];
}
}
float Sin(float rad){
int kakudo = (int)(rad*(1800/PI));
bool minus = kakudo<0;
kakudo = (minus ? -kakudo : kakudo) % 3600;
return minus ? -mysin[kakudo] : mysin[kakudo];
}
float Cos( float rad ) {
return Sin( rad+PI/2 );
}
Cosは前にsoftyaさんに教えてもらったののそのままパクりですw
この部分は「やっヴぇwww俺かっこいいwww」って感じでお気に入りの箇所だったんですが、実行速度には変えられないので元に戻します
これでsinテーブル(度数法で小数第一位まで)+cos完成と考えていいですか?
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
おつかれ様でした。
気にる所を一箇所だけ。バグではないですが。
気にる所を一箇所だけ。バグではないですが。
float mysin[3601];
void InitSin(){
int i;
for(i=0;i<3600;i++){
mysin[i]=sin((PI/(1800))*i); ← 明示キャストを希望。速度には関係ないですが。
mysin[i]=mysin[i]; ← ここいらないのでは?
}
}
float Sin(float rad){
int kakudo = (int)(rad*(1800/PI));
bool minus = kakudo<0;
kakudo = (minus ? -kakudo : kakudo) % 3600;
return minus ? -mysin[kakudo] : mysin[kakudo];
}
float Cos( float rad ) {
return Sin( rad+PI/2 );
}
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 省メモリと動作速度
ありがとうございます
該当箇所は書き直しておきました
しかし3日もかかりましたね
正直こんなにかかるとは思いませんでした
(私一人の力でやってませんが)ここまでsinテーブル書いてきていろいろ知れていい経験になったと思います
またなにかあったら質問させて頂きます
最後になりますが本当にありがとうございます
該当箇所は書き直しておきました
しかし3日もかかりましたね
正直こんなにかかるとは思いませんでした
(私一人の力でやってませんが)ここまでsinテーブル書いてきていろいろ知れていい経験になったと思います
またなにかあったら質問させて頂きます
最後になりますが本当にありがとうございます
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: 省メモリと動作速度
PSPで高速化と言うのは、こういう事の積み重ねかと思います。
つまり、知識や手間が必要という事ですね。
究極の最適化は、
・実時間の実測 → ネックとなるポイントの洗い出し
・無駄がないかアセンブラレベルのコードの確認。
・vfpuなどの活用。
・アルゴリズムのレベルからループ回数の節約方法を検討。
などなどを繰り返すことです。
がんばってください。
つまり、知識や手間が必要という事ですね。
究極の最適化は、
・実時間の実測 → ネックとなるポイントの洗い出し
・無駄がないかアセンブラレベルのコードの確認。
・vfpuなどの活用。
・アルゴリズムのレベルからループ回数の節約方法を検討。
などなどを繰り返すことです。
がんばってください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。