[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 2chのread.cgiへ]
Update time : 05/18 20:43 / Filesize : 166 KB / Number-of Response : 785
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

C、C++の最適化について語るスレ 2



1 名前:デフォルトの名無しさん mailto:sage [2007/04/29(日) 09:54:14 ]
コンパイラ性能、コンパイルオプション、コードの最適化などについて語りましょう。
主に速度面の最適化を中心としますが、サイズなどの最適化もどうぞ。
なお、OS、CPU、コンパイラなどは限定しません

前スレ

C、C++の最適化について語るスレ
pc11.2ch.net/test/read.cgi/tech/1084676298/


2 名前:デフォルトの名無しさん mailto:sage [2007/04/29(日) 12:32:25 ]
2げtt

3 名前:デフォルトの名無しさん mailto:sage [2007/04/29(日) 15:13:32 ]
ポインタ使ったほうが速いの?

4 名前:デフォルトの名無しさん mailto:sage [2007/04/29(日) 15:18:14 ]
コンテナにオブジェクト詰めるときは
newしてそのポインタを詰めるとめがっさ軽くなる

5 名前:デフォルトの名無しさん mailto:sage [2007/04/29(日) 15:36:28 ]
>>3-4
オブジェクトのコピーがボトルネックになってる場合に限るけどな。

6 名前:デフォルトの名無しさん mailto:sage [2007/05/01(火) 17:49:32 ]
GPOを行う場合、1000回計算を行うループがあったとして、10回程度ループを回して計測して、最適化することはできないでしょうか?
一旦プログラムのすべてを実行しなければならないとしたら、毎回実行条件の違う
科学計算などではどのように最適化すればよいのでしょうか?

7 名前:デフォルトの名無しさん mailto:sage [2007/05/01(火) 22:49:32 ]
それは分岐予測というカタチでハードウェアが実行している。
コンパイラはそれが機能しやすいようにする。

8 名前:デフォルトの名無しさん [2007/05/02(水) 02:20:57 ]
ダンゴさんに声かけたか?

9 名前:デフォルトの名無しさん mailto:sage [2007/05/02(水) 02:46:05 ]
GPO? PGO?

10 名前:・∀・)っ-○◎● mailto:sage [2007/05/03(木) 03:46:08 ]
 



11 名前:デフォルトの名無しさん mailto:sage [2007/05/03(木) 14:12:12 ]
ダンゴは糞だからイラネ

12 名前:デフォルトの名無しさん [2007/05/03(木) 14:48:47 ]
>>11
団子ちゃんが馬鹿にするな!

13 名前:デフォルトの名無しさん mailto:sage [2007/05/03(木) 16:02:50 ]
が?

14 名前:・∀・)っ-○◎● mailto:sage [2007/05/03(木) 16:06:59 ]
がががーが・がーがが

15 名前:デフォルトの名無しさん mailto:sage [2007/05/03(木) 18:16:38 ]
そりゃぁ、自分の基準にそって馬鹿だと思えば馬鹿にもするだろうよ。
団子じゃなくたってね。

16 名前:デフォルトの名無しさん mailto:sage [2007/05/03(木) 18:30:39 ]
int型の配列を特定の数値で埋めたいのですが、forループで一つ一つ回していく以外に
何か高速な方法はありませんか?


17 名前:デフォルトの名無しさん mailto:sage [2007/05/03(木) 18:35:44 ]
スレ違いの気がするが
・初期化
・memset

18 名前:デフォルトの名無しさん mailto:sage [2007/05/03(木) 18:37:15 ]
>>16
SSE2の使えるCPU用でいいなら、真っ当なコンパイラに適当なオプションを指定すれば、
勝手にベクタ化してくれる。
但し、極真っ当にループを書くこと。

19 名前:・∀・)っ-○◎● mailto:sage [2007/05/03(木) 18:40:24 ]
memset使えば、コンパイラによっては最適化でより高速な命令に置き換えてくれることもある。


たとえばx86なら要素数4の倍数個で16バイトアラインされてれば

for (i = 0; i < ARRAY_SIZE; i++) {
   a[i] = foo;
}



__m128i xfoo = _mm_set1_epi32(foo);
for (i = 0; i < ARRAY_SIZE; i+=4) {
   mm_store_si128(&a[i], xfoo);
}

みたいな明示的ベクトル化は可能。

20 名前:デフォルトの名無しさん mailto:sage [2007/05/03(木) 19:28:44 ]
ビット演算についての質問です。
やりたいことは、最大値511 (2^9 - 1) で負の可能性がある
あるint型の値の値域を 0〜255 に絞りたいのです。
つまり、
 x = (x <= 0 ? 0 : (x >= 255 ? 255 : x));
ですが、これを出来るだけ速くしたいのです。
(ちなみに、最終的に行いたいことはアドレス計算です)

一応自分なりに考えたのが、
 x |= (0x100 - (x >> 8)); // 最大値を制限
 x &= ~(0x100 - (x >> 31)) & 0xff; // 最小値を制限
または
 x |= ((x >> 8) + 0x7f) ^ 0x7f; // 最大値を制限
 x &= ((x >> 31) + 0x7f) ^ 0x80; // 最小値を制限
です。
最小値もある程度決めてしまって構わないのですが、
これ以上高速に値を得る方法はありませんか?



21 名前:デフォルトの名無しさん mailto:sage [2007/05/03(木) 19:39:08 ]
最小値がある程度小さいなら、最小値の制限は
x &= ~((unsigned)x >> 24);
でいいかと。

22 名前:デフォルトの名無しさん mailto:sage [2007/05/03(木) 20:27:03 ]
>>16 std::fill()

23 名前:デフォルトの名無しさん mailto:sage [2007/05/03(木) 20:29:06 ]
>>17,19
memset() は埋める値が 0 とか 0xff とかじゃないと使えないだろ。

24 名前:デフォルトの名無しさん mailto:sage [2007/05/03(木) 22:17:18 ]
>>21
それいいですね!
~の方が速そうなんですが、
最後は0xffでマスクしないとゴミがのる可能性があるので、
ちょっと変えて、((unsigned)x >> 24) ^ 0xff として使わせてもらいます。
ありがとうございました^^

25 名前:デフォルトの名無しさん mailto:sage [2007/05/03(木) 22:19:57 ]
あ、すまん。間違えてたわ。
その通り。

26 名前:デフォルトの名無しさん mailto:sage [2007/05/03(木) 22:28:45 ]
(unsigned)~x>>24
のほうが速そうに見える

27 名前:デフォルトの名無しさん mailto:sage [2007/05/03(木) 22:33:07 ]
なるほど。

28 名前:デフォルトの名無しさん mailto:sage [2007/05/03(木) 23:22:19 ]
>>26
たしかにそうですね。
と思い、コードを変更して計測してみました。
結果が、クロック単位でまったく同じだったのでおかしいと思い、
コンパイラの生成コードを見てみたのですが、、、
なんと、(((unsigned)x >> 24) ^ 0xff) が>>26とまったく同じようにコンパイルされてました
vc8すごい・・・
>>26さんもありがとうございました

29 名前:デフォルトの名無しさん mailto:sage [2007/05/03(木) 23:46:17 ]
コンパイラ<やれやれ、やっと俺の優秀さに気づいたか・・・

30 名前:デフォルトの名無しさん mailto:sage [2007/05/04(金) 00:36:41 ]
ダンゴさんに言わせれば、VCはクズだがな(笑)



31 名前:・∀・)っ-○◎● mailto:sage [2007/05/04(金) 00:47:45 ]
Pentium Pro時代の癖が抜けずに未だに
アドレッシングモード使うのを期待する場面で
ロード+レジスタ間オペレーションに展開する
VC++は駄目な子

32 名前:・∀・)っ-○◎● mailto:sage [2007/05/04(金) 00:49:21 ]
まあ、Intel謹製以外では一番マシだけどなw


33 名前:デフォルトの名無しさん [2007/05/04(金) 01:17:32 ]
C、C++の最適化について語るスレ -O2

いまさらだがスレタイはこんな感じのにスレばよかったのに。

34 名前:デフォルトの名無しさん mailto:sage [2007/05/04(金) 12:45:30 ]
AoSよりSoAの方が高速に動く理由を教えてください

35 名前:デフォルトの名無しさん mailto:sage [2007/05/04(金) 20:37:59 ]
C、C++の最適化についてダンゴ先生が篤く語るスレ
がいい

36 名前:・∀・)っ-くコ:彡- mailto:sage [2007/05/04(金) 20:40:45 ]
以下、団子に変わりましてイカがお送りします

37 名前:デフォルトの名無しさん [2007/05/05(土) 17:06:49 ]
関数の引数で、スタックのオーバーヘッドをなくす為に
const hoge_t& hoge なんて参照渡しが使われるけど
これってVC8とか今時のコンパイラでも意味ありますかね?

38 名前:デフォルトの名無しさん mailto:sage [2007/05/05(土) 17:20:44 ]
参照するとスタック使わなくなるわけでねえでがす

39 名前:デフォルトの名無しさん mailto:sage [2007/05/05(土) 17:24:20 ]
>>37
オブジェクトの作成を勝手に省略することは、
一部の例外を除いて規格上認められていないから、
今でも有効。

40 名前:デフォルトの名無しさん mailto:sage [2007/05/06(日) 00:22:09 ]
ま、ダンゴさんに言わせれば、VCはクズだがな(笑)



41 名前:・∀・)っ-くコ:彡- mailto:sage [2007/05/06(日) 00:28:51 ]
>>40はゴキブリかな

42 名前:デフォルトの名無しさん mailto:sage [2007/05/06(日) 03:45:45 ]
>>34
ものによるが、キャッシュが効きやすくなるか、ベクタ化しやすくなるか、ループの最適化をしやすくなる。
AoS の方がこれらに有効なこともあるので、ものによるとしか言えん。

43 名前:デフォルトの名無しさん [2007/05/08(火) 00:40:06 ]
グローバル変数Aを算出し、算出した関数内でAを参照したいときは、

@直読み
A算出時にローカル変数で一度算出しておき、それを参照(レジスタ参照で高速化を狙う)。Aは適当なところでローカル変数を代入

どちらがより良いソースコードになるでしょうか・・・。

@は見やすくてコード量も減りますが、いちいちRAMにアクセスしそうなので実行速度に懸念があります。
Aはローカル変数を用いることにより実行速度の向上を狙いますが、コード量の増加(ローカル変数増えまくり)や
 オブジェクトサイズに懸念があります。

いまいちどちらにしたらよいかの判断が出来ませぬ・・・。
みなさまはどうされてます?
 

44 名前:デフォルトの名無しさん mailto:sage [2007/05/08(火) 00:43:33 ]
よくわからんが、関数・グローバル変数あたり、
待避と復旧用のコードが増えるだけでそ?

あと、レジスタに振られたローカル変数は消えるから。

45 名前:デフォルトの名無しさん mailto:sage [2007/05/08(火) 00:50:12 ]
>>44
レスどうもです。
「関数・グローバル変数あたり」が分かりませんでしたが・・。

ローカル変数を用いてレジスタアクセスを狙っても結局スタックに退避したら
変わらないってことでしょうか?



46 名前:デフォルトの名無しさん mailto:sage [2007/05/08(火) 01:15:00 ]
実測するしかないだろ。常識的に考えて。

47 名前:デフォルトの名無しさん mailto:sage [2007/05/08(火) 06:09:18 ]
>>43
俺様用語で抽象的なコードの質問されてもなぁ。
自分で最低限のコードを書いて、コンパイラに最適化させてアセンブリ出力見比べてみなよ。
まぁ、>46って結論が待っているけど。

48 名前:デフォルトの名無しさん mailto:sage [2007/05/11(金) 06:47:42 ]
最適化第一法則 最適化するな
最適化第二法則 まだ最適化するな

の意味の深さがまだ理解できていないと見えるな。

49 名前:・∀・)っ-くコ:彡- mailto:sage [2007/05/12(土) 08:40:11 ]
GCCってforループのiをインクリメントからデクリメントに変えるだけで
性能上がったりするよな

VC++なんかはループの最適化だけはアグレッシブだから
ほとんど気にする必要ないんだが

50 名前:デフォルトの名無しさん mailto:sage [2007/05/12(土) 12:15:26 ]
終了条件がたまたま 0 だったりするからじゃなくて?



51 名前:・∀・)っ-くコ:彡- mailto:sage [2007/05/12(土) 12:29:07 ]
0との比較のほうが命令数が少なくてすむんだよ


52 名前:デフォルトの名無しさん mailto:sage [2007/05/12(土) 13:31:43 ]
restrictedが使えるコンパイラってアルの?

53 名前:デフォルトの名無しさん mailto:sage [2007/05/12(土) 13:33:48 ]
あります。

54 名前:デフォルトの名無しさん mailto:sage [2007/05/12(土) 13:35:58 ]
>>53
bcc32を使っているのですが、うまくいきません


55 名前:デフォルトの名無しさん mailto:sage [2007/05/12(土) 13:40:26 ]
そんなもんに期待する方が間違っています。

56 名前:デフォルトの名無しさん mailto:sage [2007/05/12(土) 13:40:26 ]
あとiccもダメでした。

57 名前:デフォルトの名無しさん mailto:sage [2007/05/12(土) 13:41:43 ]
iccではちゃんと使えます。

58 名前:デフォルトの名無しさん mailto:sage [2007/05/12(土) 13:42:04 ]
そんなもんに期待する方が間違っています。

59 名前:・∀・)っ-くコ:彡- mailto:sage [2007/05/12(土) 13:44:27 ]
iccは9.1あたりから対応してるはず。VC2005コンパチだし。

60 名前:デフォルトの名無しさん mailto:sage [2007/05/12(土) 14:29:43 ]
そもそも restricted じゃなくて restrict だな。
GCC も余裕で使える。



61 名前:デフォルトの名無しさん mailto:sage [2007/05/12(土) 14:30:50 ]
そんなもんに期待する方が間違っています。

62 名前:デフォルトの名無しさん mailto:sage [2007/05/12(土) 17:19:55 ]
VC++は、2005から__restrictが導入されている。

63 名前:デフォルトの名無しさん mailto:sage [2007/05/12(土) 23:41:50 ]
__ かよ。
C++ でも使えるってことなのかな?

64 名前:デフォルトの名無しさん mailto:sage [2007/05/13(日) 00:06:03 ]
VCはc99じゃないからね。

65 名前:デフォルトの名無しさん mailto:sage [2007/05/13(日) 01:21:12 ]
ダンゴ先生に言わせればVCはクズだしなw

66 名前:・∀・)っ-くコ:彡- mailto:sage [2007/05/13(日) 01:45:59 ]
>>65は屑

67 名前:デフォルトの名無しさん mailto:sage [2007/05/13(日) 03:40:23 ]
烏賊自重しろ

68 名前:デフォルトの名無しさん [2007/05/17(木) 16:38:10 ]
長い数式の場合、複数の文に分けて書いた方が最適化しやすいのでしょうか、それとも一気に一つの文に詰め込んでしまった方がよいのでしょうか?

69 名前:デフォルトの名無しさん mailto:sage [2007/05/17(木) 16:42:45 ]
場合による

70 名前:デフォルトの名無しさん mailto:sage [2007/05/17(木) 16:43:21 ]
っ 実測



71 名前:デフォルトの名無しさん mailto:sage [2007/05/17(木) 17:04:13 ]
そういう最適化は尚早な最適化や、個人の好みでしかない事の典型的な例

72 名前:デフォルトの名無しさん mailto:sage [2007/05/17(木) 17:29:12 ]
オーバーロードしてるような時は
コピーコンストラクタが実行されないように
分けた方がいいやね。

73 名前:デフォルトの名無しさん mailto:sage [2007/05/17(木) 17:39:47 ]
>>68
先ずは読み易く書き、適切なコンパイルオプションでコンパイルし、そこが速度上のネックになっていないか測定し、
ネックになっているようならそこで初めて、そこを抜き出して両方のケースを測定してみることだ。
まぁ、コンパイラが適当に最適化してくれるから大差ないと思うよ。

74 名前:デフォルトの名無しさん mailto:sage [2007/05/17(木) 21:24:07 ]
ダンゴさんの締めのレスが待ち遠しいな

75 名前:デフォルトの名無しさん mailto:sage [2007/05/18(金) 01:59:50 ]
団子って良く呼ばれるけど、
書き込んだら書き込んだで叩かれるんだよな

76 名前:デフォルトの名無しさん mailto:sage [2007/05/18(金) 02:04:33 ]
呼ばれてしゃしゃり出て叩かれることを学習させないと。
赤子と同じ。


77 名前:デフォルトの名無しさん mailto:sage [2007/05/18(金) 08:26:43 ]
赤子みたいなレスだなw

78 名前:デフォルトの名無しさん mailto:sage [2007/05/18(金) 11:36:25 ]
赤子はこれから学習するが
団子は学習した結果


79 名前:デフォルトの名無しさん mailto:sage [2007/05/18(金) 13:50:28 ]
スキルの無い奴の粘着人格攻撃を受けられれば、コテも一流だな。
団子の圧勝か・・・。

80 名前:デフォルトの名無しさん mailto:sage [2007/05/18(金) 20:13:30 ]
団子は好きだけど思い込みが激しいから反芻してから発言して欲しい。
オレモナー



81 名前:デフォルトの名無しさん mailto:sage [2007/05/18(金) 20:43:54 ]
試しに >>80 を反芻してみた。

込みいからが発言して欲モ激しから反芻してい団しい。 
オレ子は好きだけど思ナー


82 名前:デフォルトの名無しさん mailto:sage [2007/05/18(金) 21:04:05 ]
団子が負けたところを見たことがない
はっきり言って最強

83 名前:デフォルトの名無しさん mailto:sage [2007/05/19(土) 00:29:20 ]
逃げるが勝ちってか

84 名前:デフォルトの名無しさん mailto:sage [2007/05/19(土) 00:30:36 ]
糞壁と一緒だな

85 名前:・∀・)っ-くコ:彡- mailto:sage [2007/05/19(土) 00:38:34 ]
お塩先生に負けますた
矢田亜希子たん取られますた

86 名前:デフォルトの名無しさん mailto:sage [2007/05/24(木) 20:42:26 ]
>81
どういうアルゴリズムを適用するとその並びになるのか教えてくれ

87 名前:デフォルトの名無しさん mailto:sage [2007/05/24(木) 20:58:46 ]
反芻アルゴリズム
攪拌ではない

88 名前:デフォルトの名無しさん [2007/06/07(木) 10:55:11 ]
vectorは[]でアクセスできますが、これってメモリ上でも連続しているということでしょうか?
配列と比べても、実行速度は変わらないと考えてよいのでしょうか?

89 名前:デフォルトの名無しさん mailto:sage [2007/06/07(木) 11:01:05 ]
最新の仕様では連続してる事が保証されてた気がする。
ただ、それは別に [ ] でアクセスできるからという理由ではない。
こいつは演算子オーバーロードされてるから。
例えば deque なんかも [ ] でアクセスできるけど、
こいつはメモリ上の連続性は保証されてない。

90 名前:デフォルトの名無しさん mailto:sage [2007/06/28(木) 02:32:29 ]
>>88
vectorは連続している事が保証されているので、いざとなったら先頭アドレスを取り出して配列としてアクセスすることも出来るよ。
あと、配列の[]やvectorのoperator[]は境界チェックをしないけど、vectorのat()は境界チェックをするよ。知ってたらごめんね。



91 名前:デフォルトの名無しさん mailto:sage [2007/06/28(木) 17:21:44 ]
>>88
逆に言えば、添え字演算子[]で読み書きできるからといって、
メモリ上で要素が連続している保障があるとは限らない。
dequeとかmapとか。

92 名前:デフォルトの名無しさん mailto:sage [2007/07/15(日) 14:57:49 ]
>88の人気に嫉妬

93 名前:デフォルトの名無しさん [2007/08/03(金) 20:43:46 ]
Intel compilerのx64版を使っているのですが、
レジスタにある筈の値を何度もメモリに読みにいったり、
もう使わないローカル変数をメモリに書き込んだりしています。
ループの奥底なので許容できません。VTune で見てもボトルネックになって
いるようです。
深い理由があってのことででしょうか?
それとも、x64版の熟成が未完なのでしょうか?

32bit版との賢さの違いについてどんな印象をお持ちですか?


94 名前:デフォルトの名無しさん mailto:sage [2007/08/03(金) 21:19:37 ]
64bit版は知らんけど、32bit版もインテルが自分で言うほど
飛びぬけた性能でもないような…。

体験版で試して、俺のプログラムはVCに全敗したから、買う
のやめた。Linuxだと他に選択肢が無いのかも知れんけどね。

95 名前:デフォルトの名無しさん mailto:sage [2007/08/03(金) 21:42:37 ]
ウチの場合はICCのが何割か速かったよ。画像処理で。
GCCとVCと比較してもっとも早かった。
64bit版はさすがに知らないけど。

マルチコアならレジスタにある値だけだとあんまり信用できないからかね?

96 名前:デフォルトの名無しさん mailto:sage [2007/08/03(金) 22:02:01 ]
ポインタをdereferenceした値なんじゃないの

97 名前:デフォルトの名無しさん mailto:sage [2007/08/04(土) 01:58:07 ]
>>93
const付けられるところには全て付けてるよな?
関数ローカルのauto変数とか、クラスのメンバ関数(not変数)とかにも。

それでエイリアス問題とかが片付くから、割と変わるぞ。

98 名前:デフォルトの名無しさん mailto:sage [2007/08/04(土) 02:10:28 ]
エイリアス問題はconstじゃ解決しないぞ
restrictキーワードが要る

99 名前:デフォルトの名無しさん mailto:sage [2007/08/04(土) 03:29:23 ]
ん?
メンバ関数がconstなら、その関数内から見たらクラスのメンバ変数は皆const扱いだろ?
となると、複数のポインタor参照でメンバ変数を参照したり、キャッシュを持ったりしても実害が無いだろ?
変更がありえないんだから。
つまりエイリアスが発生しても、それが問題にならないケースがあるわけだ。
(グローバル関数経由の変更というものもあるので、確実じゃないけどな)

もちろん、クラスのメンバ以外を操作するならrestrictが必要だな。
それはおっしゃる通り。

100 名前:デフォルトの名無しさん mailto:sage [2007/08/04(土) 12:12:12 ]
constは、「プログラマが」変数を書き換えないという表明であって、
値が変化しないことの保証にはならない。

ポインタor参照経由の値は、
常にaliasの可能性があるとコンパイラはみなさなければならない。

というか、最適化のためのconstnessの判断はコンパイラがやることなので、
最適化フェーズではregisterキーワードよろしく無視されると考えていい。

と似たことを以前constでメシがナンタラというスレで書いた気がする。








[ 続きを読む ] / [ 携帯版 ]

次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<166KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef