- 1 名前:デフォルトの名無しさん mailto:sage [2007/04/29(日) 09:54:14 ]
- コンパイラ性能、コンパイルオプション、コードの最適化などについて語りましょう。
主に速度面の最適化を中心としますが、サイズなどの最適化もどうぞ。 なお、OS、CPU、コンパイラなどは限定しません 前スレ C、C++の最適化について語るスレ pc11.2ch.net/test/read.cgi/tech/1084676298/
- 481 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 01:02:33 ]
- ダンゴさんの鋭い意見が望まれるな
- 482 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 01:25:06 ]
- かわいそうな奴はもう放っとけよ
- 483 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 11:02:27 ]
- 通院中だから、ちょっと待っててね。
- 484 名前:デフォルトの名無しさん [2008/03/07(金) 14:42:19 ]
- VC++の浮動小数点ですが、
/fp:precise fast strict の中でどれが一番精度が高いのでしょうか? デフォルトのpreciseだと思っていたのですが、 floatをdoubleに変えたときの結果に一番近かったのが fastだったのですが。
- 485 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 15:48:46 ]
- >>484
まず、floatをdoubleにした結果に一番近いの意味が不明
- 486 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 17:16:52 ]
- >>484
x86のFPUはfloatだろうとdoubleだろうと、内部では80bitで計算している。 そのために、floatの計算で本来なら丸め誤差が発生するはずのところで、 誤差が発生しないという問題が生じる。 厳密に規格で決められた通りの精度で計算するためには、1つの計算が 終わるたびに丸め操作が必要になる。 その辺のコントロールをするのが/fpオプションで、fastは速度優先で 最低限の丸め操作しかしないので計算の精度が必要以上に上がってしまう。 また、どのタイミングでメモリにストアされるかによっても、計算結果が 変わってしまうので、全く同じ入力を与えても常に同じ結果になることが 保証できない。
- 487 名前:♪(*^ ・^)ノ⌒☆ mailto:sage [2008/03/07(金) 18:40:21 ]
- >>480
命令の並び順こそモダンなCPUではOoOがあるからあんまり影響しない。 レイテンシの極端に大きい命令に展開されるのがわかってる場合は アンロールしてソフトパイプライニングするのも有効。もちろんCレベルでできる。 C++なら機種依存の手続きをトレーツ(笑)にしてインターフェイスを汎用化する手もあるね。 >>481 黙れスイーツ(笑) >>**** ご希望にお答えしてお前は放置 >>483 おう、闘病がんがれよ
- 488 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 20:08:28 ]
- NGnameが増えたのか?
- 489 名前:ヾ(*´∀`*)ノ mailto:sage [2008/03/07(金) 20:57:02 ]
- どうぞどうぞ
- 490 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 00:15:33 ]
- >>486
コードが同じならメモリにストアされるタイミングも同じで、 同じ入力を与えたら同じ結果になるんじゃないの? それとも、入力ってのはソースファイル(コンパイラに対する入力)のことかな?
- 491 名前:デフォルトの名無しさん [2008/03/08(土) 00:45:47 ]
- >>490
レジスタからあふれてメモリに追い出されるときに丸めが生じる。 同じ式が違う場所にあるときに丸めるタイミングが違ってくる可能性がある。
- 492 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 00:51:19 ]
- 同じ位置にあるコードでの話じゃなかったのか。
- 493 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 01:24:27 ]
- 同じ位置にあっても、コンパイルされるたびに毎回同じ結果に
なることが保証できない。
- 494 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 01:32:41 ]
- つまり、入力ってのはソースファイル(コンパイラに対する入力)のことになるわけだね?
- 495 名前:486 mailto:sage [2008/03/08(土) 02:03:49 ]
- いや、関数に対する入力のつもりで書いたんだが。
言いたいことは491の言ってることだな。 クライアントとサーバで同じ式を書いても同じ結果にならなかったり、 デバッグ用のコードを入れたら結果が変わったり、インライン展開 されるかどうかで結果が変わってしまう。
- 496 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 02:16:10 ]
- コンパイルしてしまった後のプログラムがあって、
それの全く同じタイミングに実行される全く同じ位置のコード(マシン語レベルで)に 全く同じ入力を与える場合を想定してたんだぜ。
- 497 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 02:43:10 ]
- ダンゴさんのレスでスレが一気に加熱したな。
- 498 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 02:46:36 ]
- メモリ4倍にしたらCPUの処理速度が40%以上遅くなった。
- 499 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 02:49:01 ]
- CPU の問題じゃなくて、サイズの違うメモリを使ってるからじゃないのか?
- 500 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 09:00:59 ]
- 単純に、交換したメモリが遅いだけじゃないの?
- 501 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 09:29:12 ]
- CPU が遅くなったと言うなら、
レジスタのみの演算をぶん回して 比較しないとな。
- 502 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/03/08(土) 13:26:10 ]
- Intel入ってないだけじゃないの?
Athlon 64の前のモデルではメモリ増やすと逆に遅くなる現象があるらしーな。
- 503 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 14:39:40 ]
- PenDの速さの実感できなさ具合は異常
- 504 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 16:24:45 ]
- あぼーん推奨ワード:ダンゴさんの
- 505 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/03/08(土) 17:28:20 ]
- 同意
- 506 名前:デフォルトの名無しさん mailto:sage [2008/03/09(日) 00:40:05 ]
- ダンゴさんが復活したおかげでレス数がうなぎのぼりだな
- 507 名前:デフォルトの名無しさん mailto:sage [2008/03/09(日) 04:12:57 ]
- あぼーん推奨ワード:ダンゴさんが
- 508 名前:デフォルトの名無しさん mailto:sage [2008/03/09(日) 05:24:38 ]
- あぼーん推奨ワード:ダンゴ、団子
- 509 名前:デフォルトの名無しさん mailto:sage [2008/03/09(日) 17:06:41 ]
- だんご大家族♪
- 510 名前:デフォルトの名無しさん mailto:sage [2008/03/09(日) 22:48:39 ]
- DANGOさんのおかげでEDが直りました
- 511 名前:498 mailto:sage [2008/03/09(日) 23:25:11 ]
- superπでチェックしたが明らかにCPUトロくなった。256を1Gに変えたのだが。
- 512 名前:デフォルトの名無しさん mailto:sage [2008/03/09(日) 23:25:18 ]
- 弾固さんのおかげで層化学会に入ることができました
- 513 名前:デフォルトの名無しさん mailto:sage [2008/03/09(日) 23:26:32 ]
- どうせ128MBの板を何枚もポトペタしただけなんだろ?
- 514 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/03/09(日) 23:51:13 ]
- 板です。128kgまで耐えられます。
- 515 名前:デフォルトの名無しさん mailto:sage [2008/03/09(日) 23:54:19 ]
- 面白くないから黙ってろ
- 516 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/03/10(月) 00:03:49 ]
- >>511
OSは?Windows 2000は512MB以上はほとんど管理してないよ
- 517 名前:デフォルトの名無しさん mailto:sage [2008/03/10(月) 00:30:06 ]
- >>515
お前も面白くない。自分に適用しないジャッジを人に適用しないようにな。
- 518 名前:デフォルトの名無しさん mailto:sage [2008/03/10(月) 14:32:22 ]
- 以降、面白さを最適化するスレになりますた。
- 519 名前:デフォルトの名無しさん mailto:sage [2008/03/10(月) 14:36:11 ]
- 面白さのサイズが最小になるのか
- 520 名前:デフォルトの名無しさん mailto:sage [2008/03/10(月) 17:59:24 ]
- 以降、面白さを最適化するスレを最適化するスレになりました。
- 521 名前:デフォルトの名無しさん mailto:sage [2008/03/10(月) 20:20:10 ]
- >>1 に goto >>1000 って入れときゃいいんじゃね?
- 522 名前:デフォルトの名無しさん mailto:sage [2008/03/10(月) 22:11:35 ]
- 僕らが一つと半分のスレッド、時間にしてほぼ4年の月日を消費して分かった事、それは
どんなにメモリを必要とするプログラムを書いても副作用がなければそのプログラムは 何もせずにOSに制御を返す1024バイトにも満たないデータ列と同じだという事。
- 523 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/03/10(月) 22:18:01 ]
- いや、今わかったのはたぶんあんただけよ。
- 524 名前:デフォルトの名無しさん mailto:sage [2008/03/10(月) 22:36:50 ]
- DANGOさんのベンチマークは副作用で満たされているな
- 525 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/03/10(月) 22:52:46 ]
- それを言うな
- 526 名前:デフォルトの名無しさん mailto:sage [2008/03/11(火) 11:27:17 ]
- 副作用でスレが荒れる
- 527 名前:デフォルトの名無しさん mailto:sage [2008/03/11(火) 13:14:19 ]
- メモリ2G積んでるけどそっちがフル稼働するずっと前にCPUがまんまんになる
- 528 名前:デフォルトの名無しさん mailto:sage [2008/03/11(火) 18:32:21 ]
- 以降下ネタ禁止
- 529 名前:デフォルトの名無しさん mailto:sage [2008/03/11(火) 21:18:20 ]
- ISAバスのEMSメモリカードが遅くて泣いたのはいい思い出
- 530 名前:デフォルトの名無しさん mailto:sage [2008/03/11(火) 21:21:26 ]
- 私のPCは、CPU温度は低いのにGPUはちんちんに熱くなる。
- 531 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 13:21:14 ]
- それ普通
- 532 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 13:47:44 ]
- >>527
それは今時普通ですから
- 533 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 22:00:28 ]
- ある C++ のメソッドを アセンブラに書き換えたら、かえって実行速度が遅くなった orz
- 534 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 22:12:21 ]
- あるある。
コンパイラってマジ賢いわ。
- 535 名前:533 mailto:sage [2008/03/12(水) 22:25:43 ]
- それがさー 多倍長整数の1ビットシフトと論理積処理なんだぜ
r = (r << 1) & mask; // r, mask は多倍長整数 こんな単純な処理はキャリービットを使ったシフト命令が使えるアセンブラの方が絶対速いはずなのだが アセンブラにすると、グローバルな最適化がうまくできないみたいで、C++ よりも遅くなったみたい
- 536 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 22:28:49 ]
- そう言うときはどういう処理吐いてるか見た方がいいよ。
- 537 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 22:30:44 ]
- >>535
差し支えなければC++とasm双方晒してくれ。
- 538 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 22:31:22 ]
- 局所的な最適化は必ずしも大局的な最適化とはならない事のいい例だね。
例えば最近のコンパイラなんかは、一回のコンパイル時間が長くなっても エラーメッセージなどを丁寧に出力するから、結果的にコードを修正する時間が短くなって コンパイル回数も減り、開発時間が短くなる事に寄与している。 コンパイラ賢い。
- 539 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 23:01:49 ]
- >>535
パイプラインが詰まるようなコード書いたんじゃねーの。
- 540 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 23:05:20 ]
- キャリーっていう1つしかない資源を使う限り、
詰まらざるを得ないんじゃないかな。
- 541 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 23:19:41 ]
- 多少コードが増えてもCPIが上がれば逆転するから、安易なインラインアセンブラの使用は割に合わない。
- 542 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 12:36:23 ]
- asmのおかげで回りの最適化が効かなくなってんじゃないか?処理時間の短い関数をasmにしても逆効果だよ。
ループを含めるとか、ある程度処理時間がかかる部分をasmに直そうよ。
- 543 名前:536 mailto:sage [2008/03/13(木) 19:09:16 ]
- もちろんコンパイラが吐き出してるソースチェックしたよ
そしたら グローバルに最適化されてるってことがわかったんだよ
- 544 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 19:10:14 ]
- >>537
うーん、そのままだとちょっと差し支えがあるので、 晒せるように書き直せるかどうか試してみるよ
- 545 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 19:20:37 ]
- >グローバルに最適化
の意味が解らん
- 546 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 19:42:37 ]
- 以下のようなクラスがあって
class CShiftAnd { uint m_nReg; uint *m_pR; uint *m_pCV; uint m_exitIndex; uint m_exitMask; public: CShiftAnd(int); ~CShiftAnd(); bool setEntryState(); void transition(uchar); void transition_asm(uchar); };
- 547 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 19:42:59 ]
- bool CShiftAnd::setEntryState()
{ *m_pR |= 1; return (m_pR[m_exitIndex] & m_exitMask) != 0; } void CShiftAnd::transition(uchar ch) { uint *ptr = m_pR; uint *pCV = m_pCV + (ch * m_nReg); uint carry = 0; for(uint i = 0; i < m_nReg; ++i, ++ptr) { uint nextCarry = *ptr >> 31; *ptr = (*ptr << 1) + carry; *ptr &= *pCV++; carry = nextCarry; } }
- 548 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 19:43:53 ]
- void CShiftAnd::transition_asm(uchar ch)
{ uint *pR = m_pR; uint *pCV = m_pCV + (ch * m_nReg); uint nReg = m_nReg; __asm { mov edi, pR ;; edi = m_pR mov esi, pCV mov ecx, nReg xor eax, eax ;; clear carry L01: mov eax, [edi] adc eax, [edi] and eax, [esi] mov [edi], eax lea edi, [edi+4] lea esi, [esi+4] loop L01 } }
- 549 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 19:45:47 ]
- 以下のコードでタイムを計測した
buf のサイズは1000なので、10億回ループする { StopWatch<> sw; CShiftAnd sa(31); for(int i = 0; i < 10000 * 10; ++i) { int count = 0; for(cchar *ptr = buf; ptr < buf + sizeof(buf); ) { if( sa.setEntryState() ) count += 1; sa.transition(*ptr++); } } }
- 550 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 19:47:27 ]
- おいらの環境でタイムを計測すると
1.125秒 sa.transition(*ptr++); を sa.transition_asm(*ptr++); に変えてタイムを計測すると 1.469秒 だった
- 551 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 20:05:19 ]
- 中身全然理解してないけど
なんでedxを使わないでレジスタ変数に使われる(push/popが必要な)esiやediを使ってるの、とか あなたの読んだ最適化に関する文書に、LOOPを使うことについて何か触れられてなかったのか、とか
- 552 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 20:20:27 ]
- >>551
じゃ、アセンブラでどう書いたら高速になるのかコードを晒してくおくれ
- 553 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 20:24:49 ]
- 何が「じゃ」なんだろ。まったく話が繋がってない。
- 554 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 20:30:54 ]
- >>552
最適化技法の専門書でも読め
- 555 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 20:38:59 ]
- C++のソースレベルで見ても
ロード/ストアの形にするのも基本だし カウンタ(i)を用意して非定数のlimitと比較するくらいなら、first/last形にするのが常識だし (まあこれは0との比較に変えてるみたいだからいいか) といっても、その程度は最適化コンパイラなら当たり前にやっていることだけど
- 556 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 20:42:18 ]
- で、結局、「グローバルに最適化」とは何なのだろう。
- 557 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 21:16:13 ]
- >>538の「大局的な最適化」と同じ意味だろう。
別に何かの規格で定められた専門的な用語ではないはずだ。 いや、わかっててネチっこく絡んでるだけなら、野暮な説明だけど。
- 558 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 21:29:52 ]
- おまいらもっと速いアセンブラのコード晒してやれよ
- 559 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 21:33:39 ]
- >>557
いや、だから「どこを見てコンパイラが大域的な最適化をしていると判断したか」という話よ。 単に「自分の書いた(付け焼刃の)アセンブラより速かったから 大域的な最適化をしているに違いない」と言ってるとしか見えないわけさ。
- 560 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 21:51:33 ]
- >>559
543 名前:536[sage] 投稿日:2008/03/13(木) 19:09:16 もちろんコンパイラが吐き出してるソースチェックしたよ そしたら グローバルに最適化されてるってことがわかったんだよ
- 561 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/03/13(木) 21:55:30 ]
- VC++は、インラーインアッセンブルルルルァ使った関数はインライン展開とかできません。
- 562 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 21:58:27 ]
- 余計意味わかりませんけど。
例えば、そのグローバルな最適化によって、 >>547はどのようなアセンブラコードになるのですかね?
- 563 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 22:00:06 ]
- ☆ チン マチクタビレタ〜
マチクタビレタ〜 ☆ チン 〃 ∧_∧ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ヽ ___\(\・∀・) < 速いアセンブラソースまだ〜? \_/⊂ ⊂_ ) \_____________ / ̄ ̄ ̄ ̄ ̄ ̄ /| | ̄ ̄ ̄ ̄ ̄ ̄ ̄| | | 愛媛みかん |/
- 564 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 22:34:20 ]
- 団子さんのレスが期待されるところだ
- 565 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 22:43:23 ]
- いやもうレスしただろ
- 566 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/03/13(木) 22:57:30 ]
- SSEの使えないコードは汗んブラないのが俺のモナー
よく読んでないけど使えそうだけどな
- 567 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 23:16:51 ]
- >>559
> いや、だから「どこを見てコンパイラが大域的な最適化をしていると判断したか」という話よ。 このタイミングで急に新しい話題始めるんですかー。
- 568 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 23:17:12 ]
- loop は遅いから使わないってのは基本だと思うんだがなあ。
- 569 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/03/13(木) 23:27:44 ]
- コンパイラより自分でアセンブったコードの方が速いと根拠もなく信じてる人もたまにいるので。
- 570 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 23:29:10 ]
- そんなん信じてる馬鹿ここにはまずこないんじゃないの
- 571 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 23:31:02 ]
- x86・RISCやキャッシュてんこ盛りのプロセッサだと今時のコンパイラを超えるのは至難だろうな。
組み込み系の貧弱な石ならアセンブラの方が速い事は多々あるけど。
- 572 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 23:31:52 ]
- コンストラクタ無し/デストラクタ無し/初期化されず説明の無いメンバ変数。
速いコードは書けないが、動かないコード晒されると更にやる気を削がれるな。 >>556 SSE使えるならむしろCって考え方も。 >>568 最近はmicro op fusionとかやってるから高級な命令の方がAMDみたく都合よくなるんじゃない?
- 573 名前:デフォルトの名無しさん mailto:sage [2008/03/13(木) 23:34:07 ]
- 安価ミスった。556じゃなくて>>566
- 574 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/03/13(木) 23:36:35 ]
- VCなんかだとthisポインタはecx渡しになるからそこんとこ考えてコード組む必要がある。
- 575 名前:デフォルトの名無しさん mailto:sage [2008/03/14(金) 00:20:39 ]
- >>548
ところで、このコードは正しい結果が出るか確認したか?
- 576 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/03/14(金) 00:23:47 ]
- んでもって>>548はecx使っちゃってるね
- 577 名前:デフォルトの名無しさん mailto:sage [2008/03/14(金) 12:16:54 ]
- >>548
86のアセンブラなんて10年以上やってないんで自信ないんだが、途中でキャリーフラグ消えてないか? キャリー使わずにCで書いても同じくらいの速さのコードは出そうだが。
- 578 名前:デフォルトの名無しさん mailto:sage [2008/03/14(金) 13:01:13 ]
- >>577
mov, lea, loop はキャリーに影響しない add edi, 4 でなく lea edi, [edi + 4] とするのはそのためでもある
- 579 名前:デフォルトの名無しさん mailto:sage [2008/03/14(金) 21:39:30 ]
- >>578
andも?
- 580 名前:デフォルトの名無しさん mailto:sage [2008/03/14(金) 22:07:37 ]
- >>579
少しは自分で調べろ
- 581 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/03/15(土) 00:05:39 ]
- andは書き換えるだろ。
MMX/SSEもフラグレジスタを書き換えない。
|

|