1 名前:デフォルトの名無しさん mailto:sage [2007/04/29(日) 09:54:14 ] コンパイラ性能、コンパイルオプション、コードの最適化などについて語りましょう。 主に速度面の最適化を中心としますが、サイズなどの最適化もどうぞ。 なお、OS、CPU、コンパイラなどは限定しません 前スレ C、C++の最適化について語るスレ pc11.2ch.net/test/read.cgi/tech/1084676298/
102 名前:デフォルトの名無しさん mailto:sage [2007/08/04(土) 15:53:02 ] うーん、そういうケースも多いだろうけど constがオプティマイザに無視されるということはないと思うぞ。 以前関わったプロジェクトで、constがろくについていなかったので 片端から付けた事があるんだよ。 結果リリースビルドのバイナリが大幅に変わってしまった。 速度的にはそれほどの向上は無かったのが残念だけど(ホットスポットは変わらなかった) 全体的にconstメンバ関数のインライン化が行われていた。 約1%ほどバイナリが肥大化したのはご愛嬌^^;
103 名前:デフォルトの名無しさん mailto:sage [2007/08/04(土) 16:08:05 ] そりゃまたアホなコンパイラだな・・・ それにその例だと、速度かわらず、バイナリが増えてるんなら無意味じゃないか。
104 名前:デフォルトの名無しさん mailto:sage [2007/08/04(土) 16:12:56 ] ホットスポットが変わらないから速度の有意差が出なかったのだろ。
105 名前:デフォルトの名無しさん mailto:sage [2007/08/04(土) 19:43:09 ] >>102 そこまで言うならメンバ関数への const の有無で出力コードの変わるソースを 出してみて欲しい。
106 名前:デフォルトの名無しさん mailto:sage [2007/08/05(日) 01:23:48 ] ちょっとやってみたが、短いサンプルだとconstの有無に関わらずインライン展開されて 結局同じになってしまうな…… まあこの場合「const の有無で出力コードの変わるソース」が存在することを 証明できればいいのだから、最適化オプションの調整を含めて もうちょっと詰めてみる。 こっちもデスマ中なので何日かかるかもしれないが、期待しないで待ってろ。
107 名前:デフォルトの名無しさん mailto:sage [2007/08/05(日) 01:29:31 ] 必要なのは「出力コードが変わる」じゃなくて「速度向上に貢献する」だぜ つか、なにもデスマ中にやらんでも(´・∀・`) 元気なときにやろうぜ
108 名前:デフォルトの名無しさん mailto:sage [2007/08/05(日) 02:29:18 ] いや、>>105 がそう言っているんでな。 とりあえず「constで変わりうる」ということを出しておこうかなと。 C/C++では完全な参照透過性を保証する構文が無いから、 コンパイラにとって論理レベルでの最適化は難しいだろうが、 不可能では無い事を明示したい。 まあ今日は寝る。おやすみ。
109 名前:デフォルトの名無しさん mailto:sage [2007/08/05(日) 02:56:49 ] >>108 そこまでわかっていて不可能ではないと思う根拠はなんだろう? 楽しみにしてるよ。
110 名前:デフォルトの名無しさん mailto:sage [2007/08/06(月) 22:23:24 ] 今年プログラム初めてまだまだわからないことだらけで助けてほしいことがある。 複数のファイルより条件に合う行を抜き出して一つのファイルに出力するプログラムを作ったんですが 処理に結構時間がかかってしまいます。何とか速度向上させたいのですが何か良い方法はないでしょうか? 本当は自分でいろいろ試行錯誤してやりたいのですが分け合って時間が取れなくて書き込みました。
111 名前:デフォルトの名無しさん mailto:sage [2007/08/06(月) 22:26:47 ] グレップツール使いな
112 名前:デフォルトの名無しさん [2007/08/06(月) 22:35:17 ] >>110 秀丸つかっとけ
113 名前:デフォルトの名無しさん [2007/08/06(月) 22:36:36 ] >> 93 です。 色々アドバイス頂きながら、返信せず申し訳ありません。 const はきちんと付ける主義です。 わざわざ、{} を追加して、スコープを絞っても、ローカル変数の 無駄な書き込みを止めさせることはできませんでした。 何となく、ICC x64のコンパイル結果って回りくどい気がするのです。 命令のレイテンシとかキャッシュ効率とか考慮された結果かな?
114 名前:デフォルトの名無しさん mailto:sage [2007/08/06(月) 22:40:25 ] restrictについては言及ナシですか。
115 名前:デフォルトの名無しさん mailto:sage [2007/08/06(月) 23:06:13 ] つーか、具体的なコードも出さずにあーだこーだ言われても 「あーそうですか」としか言いようがないなぁ。
116 名前:デフォルトの名無しさん [2007/08/08(水) 23:24:43 ] >>114 何故か書き込み不能になった返信がさらに遅れました。 restrictを使っても、コンパイル結果が同じでした。 仕事絡みなのでコードを出せません。ご了承下さい。 ごく一部を出しても、実害はないと思いますがバレると 厄介なことになりますもので...
117 名前:デフォルトの名無しさん mailto:sage [2007/08/08(水) 23:26:13 ] 別にその仕事とは全く関係ないコードを書けばいいのに。
118 名前:デフォルトの名無しさん mailto:sage [2007/08/09(木) 02:19:54 ] ○○○は糞、だけど証拠は出せません いい流れだ
119 名前:デフォルトの名無しさん mailto:sage [2007/08/09(木) 03:19:58 ] constによる最適化を主張する俺が戻ってきましたよ とりあえずサンプルを作るのは諦めました。そこで 既存のプロジェクトからメンバ関数のconstを外す ⇒ エラーが出たところだけconstに戻す という手順で相違点を調べました。(バージョン管理ツールは便利だねえ) >>102 の環境はVC7.1でしたがライセンスの関係で問題があるので 今回の環境は別のプロジェクトのCodeWarriorです。 で、リリースビルドの結果は以下の通り。 全関数(メンバ関数でないものやライブラリも含む) 12256個 constメンバ関数 253個 検証時にconstを削除出来なかったメンバ関数 24個 const削除前のコードサイズ 2899400 bytes const削除後のコードサイズ 2899084 bytes constを付けた方がコードサイズが増える傾向がありますが、CodeWarriorの場合は インラインされやすくなるという傾向はありませんでした。 また、極端にパフォーマンスが変化するということはありませんでした。 (づづく)
120 名前:デフォルトの名無しさん mailto:sage [2007/08/09(木) 03:40:23 ] 逆アセンブリで見られる具体的な差異としては const有りだと分岐命令の後に来ている命令が const無しだと分岐命令の前に来ている という現象が所々に見られました。 いつ評価しても同じなら分岐の後で評価したほうが得、ということなんでしょうか。 (遅延評価に似てる?) サンプルを上げようかと思ったけど、きわめて眠いのでまた今度。 明日か明後日までに適当なアップローダの紹介を希望。 ではおやすみなさい。
121 名前:デフォルトの名無しさん mailto:sage [2007/08/09(木) 07:15:32 ] 分岐命令をまたいで命令が移動するってのは、動作が変わってるような気がする。 よくわからんからサンプルが欲しいな。ろだ↓ kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm
122 名前:デフォルトの名無しさん mailto:sage [2007/08/09(木) 10:42:03 ] ほい、上げておいた。 ttp://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.cgi?mode=thr&no=4841 全部上げるわけにもいかんので加工してある。 詳細は添付のreadme.txtを読んでくれ。 じゃ俺は戦場に戻る。
123 名前:デフォルトの名無しさん mailto:sage [2007/08/10(金) 09:31:04 ] >>122 リストファイル中のソースとの対応がずれてたり、命令数の違いでアドレス部が ずれてたりしてるけど、本当に命令レベルの違いだけを抽出すると、2箇所だけになった。 -- const無し: lw v1,-21056(v0) addiu a0,v1,436 lw v1,436(v1) const付き: lw a0,-20672(v0) lw v1,436(a0) -- const無し: lw v0,-21056(v0) addiu v1,v0,436 lw v0,436(v0) const付き: lw v1,-20672(v0) lw v0,436(v1) --
124 名前:123 mailto:sage [2007/08/10(金) 09:54:07 ] 2箇所いずれも app->CheckMenu() のところね。逆読みすると、 app 内のポインタが指す配列か構造体から1つ値を読み出してるって感じ なんだけど、やっぱり CheckMenu() のソースが欲しいな。ダメ? const無しのほうにある addiu の結果は使われて無いように見える。 あれ? const 付けたほうがコード増えるって言ってたけど、ここでは 1命令減ってるね。
125 名前:123 mailto:sage [2007/08/10(金) 10:03:26 ] const の有無で最適化に影響が出てるんじゃなくて、オーバーロードに影響が 出て処理が変わってるだけじゃないだろうか? たとえば std::bitset::operator [] (size_t) なんかだと、 const 版は単に bool が 返るけど、非 const 版は代入もできるプロキシオブジェクトが返るのでかなり 違った処理になるはず。
126 名前:123 mailto:sage [2007/08/10(金) 10:31:24 ] あ、 addiu の結果はその後の sw で使われるみたい。 app のメンバオブジェクトについて const 版が int を返して、 非 const 版が int& を返すようなオーバーロードが使われてる予感。 んで int& だと続く書き込みに使いまわせるからレジスタに置かれた、と。
127 名前:デフォルトの名無しさん mailto:sage [2007/08/10(金) 11:09:19 ] やっぱり、単純にはなんとも言えないという結論か。
128 名前:デフォルトの名無しさん mailto:sage [2007/08/10(金) 21:42:46 ] いや、大方の予想通りメンバ関数の const は最適化の助けにはならないって結論だろう。
129 名前:デフォルトの名無しさん mailto:sage [2007/08/12(日) 22:50:05 ] お待たせしました。一時帰宅しました。 辛辣なツッコミを期待していたんだけど、ちょっと物足りないかしら。 まあ、相手してくれてありがとう。 以下質問に対するごお返答。 >>122 CheckMenu()は以下のようなコードになっている。オーバーロードはされていない。 bool CApplication::CheckMenu(int n) { return (m_MenuStatus == n); } ちなみにappはCApplication型のグローバル変数。constではない。 >>128 出力バイナリは違っているのに、そう言いきれるのはなぜ?
130 名前:デフォルトの名無しさん mailto:sage [2007/08/12(日) 22:51:52 ] 小林洋平
131 名前:デフォルトの名無しさん mailto:sage [2007/08/12(日) 23:42:01 ] >>129 関数の中身を晒してくれてありがとう。そういうことなら、素の int 型メンバ変数の 読み取りについてコンパイラ内部で >>126 の言うオーバーロードと似たような扱いが されているんだろう。 今回の例では const が無い場合に int& をキャッシュするために命令数が一つ 増えたとすると、前後の処理内容によってはその int& のキャッシュによって効率が 上がることも考えられる。いつでも const を付けたほうが効率が良いとは言えない。 今回の例で、コンパイラが const 無しの場合に const 付きの場合と同じコードを 吐いても何ら規格に違反しない。最適化の詰めが甘かっただけとも言える。
132 名前:デフォルトの名無しさん mailto:sage [2007/08/13(月) 10:42:15 ] constは保守のための手助けみたいなもんだろ mutableしてない変数に代入しようとしてたらエラー吐くだけの
133 名前:デフォルトの名無しさん mailto:sage [2007/08/13(月) 14:57:53 ] gcc の _attribute((const)) みたいなもんがあればいいのかも。 ・関数の戻り値が引数とインスタンスの内容にのみ依存する。 つまり、 class Test { public: int foo() __attribute__((const)); void bar() const; }; Test T; int a = T.foo(); T.bar(); int b = T.foo(); // int b = a; に最適化できる。
134 名前:デフォルトの名無しさん mailto:sage [2007/08/14(火) 02:07:27 ] >>132 変数定義時の const はそうでもないよ。 const 付きで宣言された変数は ポインタや参照を関数に渡した後でも、値が元のままであることを期待して 最適化してもいい。 これに対してポインタ・参照の指す先の型や、メンバ関数に付ける const は ほとんどコード生成に影響しないという話。
135 名前:デフォルトの名無しさん mailto:sage [2007/08/14(火) 02:10:47 ] >>133 それはダメでしょ。 T の宣言に const が付いてないので T.bar() の中で const_cast して 値を変更しても合法なはず。
136 名前:デフォルトの名無しさん mailto:sage [2007/08/14(火) 02:59:32 ] intメンバ変数一個のstructで試してみたが、 >ポインタや参照を関数に渡した後 では読み直しをやってるなあ。 環境はVC8とgcc3.4.4(cygwin)
137 名前:デフォルトの名無しさん mailto:sage [2007/08/14(火) 03:34:58 ] >>136 どんなソースで試したの? 以下のソースだと s に対する const によって読み直しが消えて return 10 に最適化される。 const 外すと当然メモリ上の s.x が読み出される。 struct S { int x; }; void f(struct S const* p); int g(void) { struct S const s = { 10 }; f(&s); return s.x; }
138 名前:137 mailto:sage [2007/08/14(火) 03:35:31 ] あ、確認した環境は Cygwin gcc 3.4.4 の -O3 ね。
139 名前:デフォルトの名無しさん mailto:sage [2007/08/14(火) 09:55:00 ] 似せるとこういう感じ。gccは-O3、vc8は/Oxです。 struct S { S(int x_):x(x_){} int x; }; void f(struct S const * p); int g(void) { struct S const s(10); f(&s); return s.x; } つーか分からないのは仕方ないか。ということで struct S { S(int x_):x(x_){} int x; int getX() const { return x; } }; void f(struct S const * p); int h(int); int g(void) { struct S const s(10); h(s.getX()); f(&s); return s.getX(); } vc8もgcc3.4.4も、分かってるんだか分かってないんだか分からないコードを吐く。 さらに、このコードの int x を const int x にすると、gccは読み直しをしなくなる。 これはsのconst修飾に依存しない。(あれれ?)
140 名前:デフォルトの名無しさん mailto:sage [2007/08/14(火) 10:20:39 ] >>139 ほんとだ。これは期待はずれだなぁ。 コンストラクタ内での代入を許すために const として定義されたという情報が 途切れてしまっている、って感じ? メンバのほうに const を付ければ代入を許すタイミングは無いから、 >>137 と 同様に最適化できる、と。
141 名前:デフォルトの名無しさん [2007/08/21(火) 08:34:45 ] const 談義中に割り込み質問ですみません。 VTune で、Clockticks をサンプリングすると"No Samples were collected." になってしまいます。 Sample After Value を変えろ、との記述を見つけて試しましたが、 うまくいきません。(他の event は収集できます) 対策をご存知の方はいらっしゃらないでしょうか?
142 名前:デフォルトの名無しさん [2007/08/21(火) 21:48:51 ] >>141 です。自己解決しました。 使っていたのが一つ前のバージョンのVTune だったので、 quad core に対応していなかったようです。 最新版の体験版をインストールしたらうまくいきました。 それにしても、何のエラーメッセージも出ず、Clockticks だけ収集できないとは、恐ろしい。
143 名前:デフォルトの名無しさん [2007/08/25(土) 12:59:29 ] switchの場合分けにおいて、記述したcase以外は絶対にありえないと コンパイラにヒント出す方法って無いですか? 分岐の先頭でcase以外を範囲外として弾くのが状況として ありえないのでもったいないです。 環境非依存でもVC6,7,8限定の方法でもかまいません。 よろしくお願いします。
144 名前:デフォルトの名無しさん mailto:sage [2007/08/25(土) 13:51:02 ] >>143 こういう場合だったら、 switch(hoge) { case 1: //1の処理 case 2: //2の処理 default: //ここに来ることは絶対にない } こうすればいいんでないの? switch(hoge) { case 1: //1の処理 default: //2の処理 }
145 名前:デフォルトの名無しさん mailto:sage [2007/08/25(土) 13:58:11 ] >>143 環境非依存ではそんなものはない。 c++であれば、enum型を使うことで慮ってくれるコンパイラがあるかもしれない。
146 名前:デフォルトの名無しさん mailto:143 [2007/08/25(土) 14:40:46 ] >>144 アセンブラコードを見てみたところ 1・範囲外チェック 2・テーブルジャンプ という流れにコンパイルされていました。 case 1: //1の処理 default: //2の処理 これだとdefaultの処理+テーブルジャンプの処理になってしまって、 結果的に範囲外チェックしているのと負荷は変わらないようです。 >>145 enum試してみます。 ありがとうございました。
147 名前:143 mailto:sage [2007/08/25(土) 14:41:25 ] sage失敗すみません
148 名前:デフォルトの名無しさん mailto:sage [2007/08/25(土) 14:51:29 ] VC7以降なら __assume を使え
149 名前:144 mailto:sage [2007/08/25(土) 15:11:09 ] >>146 なるほど。こちらが勉強させてもらいました。 確かに範囲外だったら大変だから、コンパイラとしてはチェックせざるをえないんだね。
150 名前:デフォルトの名無しさん mailto:sage [2007/08/25(土) 15:28:49 ] >>143 >144の前者のケースなら、 switch (hoge) { case 1: ...; case 2: default: ...; } でいいんでない?
151 名前:デフォルトの名無しさん mailto:sage [2007/08/25(土) 15:29:37 ] つーか、二項しかないのにテーブルジャンプにしか最適化できないコンパイラが蛸な希ガス。
152 名前:143 mailto:sage [2007/08/25(土) 15:41:13 ] >>148 __assumeが意図にかなっているようです。ありがとうございました。
153 名前:デフォルトの名無しさん mailto:sage [2007/08/25(土) 20:23:00 ] >>143 gcc限定ならコメントでなんか記述すればコンパイラが理解してくれた気がする。
154 名前:・∀・)っ-くコ:彡- mailto:sage [2007/08/25(土) 20:54:24 ] 関数テーブル+__forceinlineじゃ駄目だったっけ
155 名前:デフォルトの名無しさん mailto:sage [2007/08/25(土) 21:02:19 ] gccはassert()が__assumeと同じ動作したはず。
156 名前:デフォルトの名無しさん mailto:sage [2007/09/24(月) 00:02:22 ] assert(0);だな
157 名前:デフォルトの名無しさん mailto:sage [2007/09/24(月) 13:53:56 ] ♪ ∧,, ∧ ♪ ♪ ∧,, ∧´・ω・) 美脚♪ ∧,, ∧´・ω・) ) ♪∧,, ∧´・ω・) )っ__フ ♪ ∧,, ∧ ∧,, ∧´・ω・) )っ__フ(_/ 彡 .∧,, ∧ ) (´・ω・) )っ__フ(_/彡 ∧,, ∧ ) ) (っ )っ__フ(_/彡 .∧,, ∧ ) ) Οノ ( __フ(_/彡 ∧,, ∧ ) ) Οノ ヽ_) (_/彡 ( ) ) Οノ 'ヽ_) ( ) Οノ 'ヽ_) (ゝ. Οノ 'ヽ_) ♪ ♪ ミ ヽ_)
158 名前:デフォルトの名無しさん mailto:sage [2007/10/06(土) 14:06:35 ] C++特有じゃないとは思いますが質問させてください。 ある処理をループしようと思っているんですが、その時に、 カーソルとして使用するポインタを(ローカル変数として)毎回宣言するのと、 あらかじめ外部で宣言したものを使いまわすのではどちらが高速なのでしょうか?
159 名前:デフォルトの名無しさん mailto:sage [2007/10/06(土) 14:39:57 ] >>158 大丈夫、そんなもんは真っ先にコンパイラの最適化の餌食になるから。 それ以前に、ポインタで回すよりも配列参照で回す方が速いかも知れない。 いずれにしても、ケース・バイ・ケースだから実測するべし。
160 名前:デフォルトの名無しさん mailto:sage [2007/10/06(土) 14:41:04 ] ♪ ∧,, ∧ ♪ ♪ ∧,, ∧´・ω・) 美脚♪ ∧,, ∧´・ω・) ) ♪∧,, ∧´・ω・) )っ__フ ♪ ∧,, ∧ ∧,, ∧´・ω・) )っ__フ(_/ 彡 .∧,, ∧ ) (´・ω・) )っ__フ(_/彡 ∧,, ∧ ) ) (っ )っ__フ(_/彡 .∧,, ∧ ) ) Οノ ( __フ(_/彡 ∧,, ∧ ) ) Οノ ヽ_) (_/彡 ( ) ) Οノ 'ヽ_) ( ) Οノ 'ヽ_) (ゝ. Οノ 'ヽ_) ♪ ♪ ミ ヽ_)
161 名前:158 mailto:sage [2007/10/06(土) 15:01:50 ] >>159 なるほど。コンパイラに頼れそうですね。 配列については任意の位置に追加、削除等の関係から使えませんでした。 ありがとうございました。
162 名前:poooh ◆manko/yek. mailto:sage [2007/10/06(土) 16:10:39 ] グローバル変数は最適化に良くない。これ豆知識な。
163 名前:デフォルトの名無しさん mailto:sage [2007/10/06(土) 17:34:59 ] グローバル変数は最適化に良い。これ豆知識な。
164 名前:デフォルトの名無しさん mailto:sage [2007/10/06(土) 17:54:04 ] 確かに、既存ソフトの高速化の仕事をしていると、グローバル変数があったら狙い目だとは思うけどね。
165 名前:デフォルトの名無しさん mailto:sage [2007/10/06(土) 18:27:36 ] >>164 高速化の仕事ってどんな感じなの? 今の職場では高速化の効果が工数の割に合わないと言われることが多くて バグ改修時についでに高速化する程度しかやらせて貰えない。 既存機能を維持しつつどうやって安全に高速化してるの? グローバル変数触るなら単体テストだけじゃ足りないよね?
166 名前:デフォルトの名無しさん mailto:sage [2007/10/06(土) 20:10:46 ] 既存機能を維持しないでどうやって危険に高速化してるの? そんなんだからやらせて貰えないんだぜw?
167 名前:デフォルトの名無しさん mailto:sage [2007/10/06(土) 20:12:21 ] 単体テストで完全に見えるスコープで、グローバル使いまくる馬鹿は沢山いる
168 名前:164 mailto:sage [2007/10/06(土) 21:00:33 ] 高速化で受ける業務はソースで引き渡しだから、コード解析結果と単体テスト結果しか出さない罠。
169 名前:165 mailto:sage [2007/10/06(土) 21:36:19 ] >>168 高速化で受けた業務なら性能試験はやるんじゃないの? 単体テストしかしないなら関数単位の高速化なのかな? ライブラリ系? 参考までに、使ってる測定ツールとか教えてくれないかな。 それにしても、コード解析結果と単体テスト結果で話がつくとはな。 俺んとこだと結合試験と性能試験やらずに改修完了なんてまず了承されないよ。
170 名前:デフォルトの名無しさん mailto:sage [2007/10/06(土) 21:53:07 ] そりゃぁ、「何」で金取っているかの違いだろ。 依頼主だって全部の環境晒せるような物ばかりとは限らんわけだし。
171 名前:デフォルトの名無しさん mailto:sage [2007/10/06(土) 22:17:43 ] 結合と性試験やらずに
172 名前:デフォルトの名無しさん mailto:sage [2007/10/07(日) 21:26:42 ] 単体テスト=手淫
173 名前:デフォルトの名無しさん mailto:sage [2007/10/11(木) 07:30:27 ] ♪ ∧,, ∧ ♪ ♪ ∧,, ∧´・ω・) 美脚♪ ∧,, ∧´・ω・) ) ♪∧,, ∧´・ω・) )っ__フ ♪ ∧,, ∧ ∧,, ∧´・ω・) )っ__フ(_/ 彡 .∧,, ∧ ) (´・ω・) )っ__フ(_/彡 ∧,, ∧ ) ) (っ )っ__フ(_/彡 .∧,, ∧ ) ) Οノ ( __フ(_/彡 ∧,, ∧ ) ) Οノ ヽ_) (_/彡 ( ) ) Οノ 'ヽ_) ( ) Οノ 'ヽ_) (ゝ. Οノ 'ヽ_) ♪ ♪ ミ ヽ_)
174 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 08:10:23 ] for (int i=10;i--;) { //ループの中身 } って for (int i=0;i<10;i++) { //ループの中身 } より高速?
175 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 10:40:19 ] >>174 上の方がループの回数が多いから遅い。
176 名前:デフォルトの名無しさん [2007/10/17(水) 12:55:44 ] すみません for (int i=0;i<9;i++) { //ループの中身 } でした
177 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 13:16:29 ] >>176 >175は間違い。>174でループ回数は同じになっている。 で、どちらも同じ速度のコードになったよ(icc -fastで)。 実測したら、後者の方が気持ち速かった。と言っても、差は10msオーダーだけど。 -- for (int i = 0x7000 * 0x10000; i--;) func(); for (int i = 0; i < 0x7000 * 0x10000; i++) func(); --
178 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 13:32:58 ] 速度は実測が基本。
179 名前:デフォルトの名無しさん mailto:sage [2007/10/17(水) 15:04:30 ] >>177 ありがとう、やっぱりふつうに記述した方が、コンパイラにとってもいいようですね。
180 名前:・∀・)っ-くコ:彡- mailto:sage [2007/10/18(木) 00:31:08 ] forよりdo-whileが速い。 まあ自動で最適化してくれるけど
181 名前:デフォルトの名無しさん [2007/10/18(木) 10:54:47 ] /*1*/ for (i = 0; i < n; i++) これと、誘導変数を使った /*2*/ for (ii = -n; ii < 0; ii++) i = n + ii; それぞれについて、生成コードを予想 また実際の処理系に生成させたコードを評価せよ (n点)
182 名前:デフォルトの名無しさん mailto:sage [2007/10/18(木) 12:17:32 ] 変数の型が分からないと予想できねえよ。
183 名前:デフォルトの名無しさん mailto:sage [2007/10/18(木) 12:38:28 ] nは正数?
184 名前:デフォルトの名無しさん mailto:sage [2007/10/18(木) 12:41:36 ] クラスかもな。
185 名前:デフォルトの名無しさん mailto:sage [2007/10/18(木) 13:05:00 ] 宿題?
186 名前:デフォルトの名無しさん mailto:sage [2007/10/18(木) 13:39:29 ] 実行コストについてはダウンカウンタと大差ない感じ。 こりゃ使える。いただき。 a[i]みたいにiをインデックスで使う場面では a[n+ii]に対して&a[n]==a+nがループ内不変になるね。 つかiは符号付き整数だろw で、おれ何点?
187 名前:519 mailto:sage [2007/10/18(木) 13:41:59 ] for文の中身は?変数がintだとすると for (i = 0; i < n; i++); は i=n; という式に展開される可能性がある。 for (ii = -n; ii < 0; ii++) i = n + ii; もnが定数ならば定数代入式に展開される可能性がある。 ていう最適化機能がgccにあったような…?記憶違い?
188 名前:デフォルトの名無しさん mailto:sage [2007/10/18(木) 16:04:41 ] 空ループの話で盛り上がって 参りました
189 名前:デフォルトの名無しさん mailto:sage [2007/10/18(木) 16:18:58 ] 全然
190 名前:デフォルトの名無しさん [2007/10/19(金) 09:21:06 ] 乱数が100個必要だとして、単にループで100回乱数を発生させるのではなく、 1つの乱数から、分割するなどして100個効率よく発生させることはできないでしょうか?
191 名前:デフォルトの名無しさん mailto:sage [2007/10/19(金) 09:28:51 ] 分割って何? 並列化するってこと? 100個乱数拾うだけならたいした変化は無いと思われ
192 名前:デフォルトの名無しさん mailto:sage [2007/10/19(金) 09:43:07 ] 使い道や欲しい乱数の範囲など具体的に
193 名前:デフォルトの名無しさん mailto:sage [2007/10/19(金) 12:21:09 ] MTなら実装によっては624個の乱数が一度に得られる でも内部的にはループだしな
194 名前:デフォルトの名無しさん mailto:sage [2007/10/19(金) 18:51:21 ] >>190 64bitの乱数があったとしてそれをそれを8bit区切りに4つに分けて 8bitの乱数4つとして使えるかってこと? 乱数の質は悪くなると思うけど、どうだろ?
195 名前:190 mailto:sage [2007/10/20(土) 05:36:18 ] 用途はモンテカルロシミュレーションです。 現在はMTを使っています。 計算精度は32bitのfloatでやっているのですが、乱数は64bitのdoubleなので、 それを単純に上位と下位に分けて、一回で2回分使えないかと考えています。 もうひとつ考えているのは、64bitで生成された乱数を、ローテートで1bitずつずらして 一回のMTで64個の乱数が生成できないかということです。 ただ、この場合、乱数の質が元のMTに対してどのようになってくるのかがわかりません。
196 名前:デフォルトの名無しさん mailto:sage [2007/10/20(土) 05:45:19 ] MTやめてXorShift使うとか
197 名前:デフォルトの名無しさん mailto:sage [2007/10/20(土) 06:46:44 ] >>195 少なくとも2番目の方法はいくない。 例えば一番左のビットが0の場合、左にローテートしたら元の数の2倍になる。 つまり64個の乱数の中に、大量のaとa*2が入り込む非常に膣の悪い乱数になるよ。
198 名前:デフォルトの名無しさん mailto:sage [2007/10/20(土) 07:42:54 ] >膣の悪い乱数 乱れすぎw
199 名前:デフォルトの名無しさん mailto:sage [2007/10/20(土) 08:45:07 ] >>195 最初の方法もダメ。 MTのdoubleは基本的に仮数部32bitなので分割した下の方は精度が腐る。 仮数部53bitの方は乱数を2個使っているし。
200 名前:190 [2007/10/20(土) 10:15:36 ] 皆さんありがとうございます。 とりあえず、2^128-1周期のXorShiftを使ってみようと思います。 ところでXorShiftのseedのとり方ですが、オリジナルの文献では x=123456789,y=362436069,z=521288629,w=88675123; となっていますが、たとえば、x=1,y=2,z=3,w=4;とすると最初の 数十個は 2061 6175 4 8224 4194381 8396986 8388750 25174430 8652983179 25875070649 8636205711 60369541016 17600805477257 35210146488062 52785194351115 70428979519260 36239912164446735 ように非常に悪い乱数系列になってしまいます。 最初の数百個を捨てればよいのかもしれませんが、seedの選び方には何か決まりがあるのでしょうか?
201 名前:デフォルトの名無しさん mailto:sage [2007/10/20(土) 13:19:11 ] >>190 sineくれくれ厨
202 名前:デフォルトの名無しさん mailto:sage [2007/10/20(土) 14:14:15 ] お前がsine