- 1 名前:デフォルトの名無しさん mailto:sage [2007/04/29(日) 09:54:14 ]
- コンパイラ性能、コンパイルオプション、コードの最適化などについて語りましょう。
主に速度面の最適化を中心としますが、サイズなどの最適化もどうぞ。 なお、OS、CPU、コンパイラなどは限定しません 前スレ C、C++の最適化について語るスレ pc11.2ch.net/test/read.cgi/tech/1084676298/
- 293 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 03:13:17 ]
- 変数は参照で、
関数はインライン関数で、 型は typedef で、 名前空間は namespace a = b; で、 クラステンプレートは継承でそれぞれ可能ではある。 ただ、インライン関数使うのと、 クラステンプレートを継承するのとは、 結構面倒臭い。
- 294 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 03:16:11 ]
- このスレ地味に常駐多くないかい
- 295 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 12:27:22 ]
- C++0xであるかも知れないが、テンプレートのエイリアスは作れないよな。
typedef std::vector my_vector; みたいなの。>>293にも書いてある継承は可能ってレベルではない。 コンストラクタやらオペレータやら全部知っていて、尚かつ書かないといけない。
- 296 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 12:33:01 ]
- オペレータは必要ないと思う。
コンストラクタは作らないとダメだけど。
- 297 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 13:55:01 ]
- >>296これで例として成立してるか自身無いけど。
継承しちゃうとoperatorの返す型と継承した型が異なっちゃうからうまくいかない。 struct c { int v; c operator+(int n) { c t; t.v = v + n; return t; } }; struct d:public c {}; main() { d e, f; f + 1; // OK e = f; // OK e = f + 1; // Error }
- 298 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 14:01:54 ]
- >>297
ああ、なるほど。 というか、色んな状況を考えると継承では不完全なのか。
- 299 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 16:10:51 ]
- if(hoge.piyo == hogehoge.piyo)
hoge.piyo = hoge.piyo & ~sym.att; こんなのはこれ以上どうにもなりませんよね?
- 300 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 18:04:15 ]
- 分岐は無くせるけどね。
hoge.piyo = ~(sym.att & -(hoge.piyo==hogehoge.piyo) & hoge.piyo; x86でPentiumPro以降に限定するなら hoge.piyo = ~(hoge.piyo == hogehoge.piyo ? sym.att : 0) & hoge.piyo; はCMOVになる可能性がある。 SSEで書けば次のようにも出来る。 // hoge.piyo = ~(sym.att & -(hoge.piyo==hogehoge.piyo) & hoge.piyo; hige.piyo = _mm_andnot_ps(_mm_and_ps(sym.att, _mm_cmpeq_ps(hoge.piyo, hogehoge.piyo)), hoge.piyo); ただSIMD以外は保守性が悪くなるだけであんま効果無いと思う。 実測した方がいい。
- 301 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 20:29:28 ]
- >>300
なるほど・・-ってのを初めてみたんで調べてきます、ありがとうございます
- 302 名前:デフォルトの名無しさん mailto:sage [2008/02/03(日) 23:44:47 ]
- ANSI Cの仕様ではA==Bが真なら1になるから-1(全ビットON)にしてマスク作ってるだけだよ。
x86なら分岐せずにSETcc + NEGにコンパイルされるはず。
- 303 名前:デフォルトの名無しさん mailto:sage [2008/02/04(月) 00:57:10 ]
- 偉そうな割には右括弧が足りないぞ。
- 304 名前:デフォルトの名無しさん mailto:sage [2008/02/04(月) 01:00:29 ]
- どの道やってること同じではないのか
- 305 名前:デフォルトの名無しさん mailto:sage [2008/02/04(月) 13:36:34 ]
- まぁ、>299程度ならコンパイラに任せて実測してみてからだな。
CMOVになったところで大した差は出ないだろ。
- 306 名前:デフォルトの名無しさん mailto:sage [2008/02/04(月) 13:37:59 ]
- Windows環境でのファイルなんかのコピーを大きくする手段ってないですよね・・
どのみちOSの機能頼りなわけだから
- 307 名前:デフォルトの名無しさん mailto:sage [2008/02/04(月) 13:39:36 ]
- コピーしたつもりがおっきくなっちゃうのかー。そりゃねーな。
- 308 名前:デフォルトの名無しさん mailto:sage [2008/02/04(月) 13:41:01 ]
- すんません、ガチで寝ぼけてる
早くする、ですほんとごめんなさいごめんなさいごえmんあい
- 309 名前:デフォルトの名無しさん mailto:sage [2008/02/04(月) 13:43:14 ]
- 早くする手段ならいくらでもあるだろ。
速いかどうかは知らんが。
- 310 名前:デフォルトの名無しさん [2008/02/04(月) 13:48:24 ]
- ストライピング
コードレベルの最適化とは無縁だが。
- 311 名前:デフォルトの名無しさん mailto:sage [2008/02/04(月) 13:54:21 ]
- 高速化っていうんだから速くか
ストライピング、調べてきました それだと送り先が2箇所なのかな・・・ コピー元も先も1箇所なんです というかコードレベルって話じゃないですよね、把握しました
- 312 名前:デフォルトの名無しさん mailto:sage [2008/02/04(月) 13:55:51 ]
- 単純にバッファをいじるとか
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet /Control/Session Manager/Memory Management ここの数値を というか普通こんなことしねえよな・・
- 313 名前:デフォルトの名無しさん mailto:sage [2008/02/04(月) 13:58:42 ]
- >>311
実際問題、ファイルアクセスの速度はデバイス側の事情で決まってしまう。 と言うことで、単純に速くする方法はない。 寧ろ、本当にファイルコピーの時間が問題なのか、例えばレスポンスが問題なのか、検討した方がいい。
- 314 名前:312 mailto:sage [2008/02/04(月) 13:59:50 ]
- うちの環境だと10Mにしてるけどよく考えたら馬鹿すぎる方法だ
確か再起動必要だった気がするし
- 315 名前:311 mailto:sage [2008/02/04(月) 14:12:46 ]
- >>313
最近、.NETFrameworkというものを触ってみまして 色々試してみようとコンソールなんですがファイルをコピー(バックアップ?)する ものを作ってみたんですが、そこでコピー自体速くならないかなあと思った次第です >>312>>314 再起動必要じゃあれですね・・・ Win32APIとかってのもWindowsの機能を使うやつだって聞いたんで それでファイルのコピーするとこを実装すれば速いんだろうか
- 316 名前:デフォルトの名無しさん mailto:sage [2008/02/04(月) 14:20:28 ]
- >>315
先ず、.Netって時点でスレ違い。 次に、ファイルコピー自体の速度はデバイス依存だ。 .Netでファイルコピーしていて遅いと思うのなら、コードレベルの最適化ではなく.Netの使い方の問題だ。
- 317 名前:デフォルトの名無しさん mailto:sage [2008/02/04(月) 14:23:52 ]
- C/C++でファイルコピーなんてファイル開いて読み取って書き込むの繰り返しなんだからさ
たぶん.NETでもAPIでも使った方が良い ということでもうそれで完成でいいじゃない
- 318 名前:デフォルトの名無しさん mailto:sage [2008/02/04(月) 22:14:23 ]
- >>311
Windows 限定なら FastCopy.exe のソースとか見ればいいんじゃないか。
- 319 名前:デフォルトの名無しさん mailto:sage [2008/02/04(月) 22:28:22 ]
- オープンソースとか見ると趣味人でもない限りC/C++やWinAPIを使うのってことがどういうことかわかっちゃうよな
- 320 名前:デフォルトの名無しさん mailto:sage [2008/02/04(月) 23:24:12 ]
- 俺は、お前の言ってることがどういうことかわからん。
- 321 名前:デフォルトの名無しさん mailto:sage [2008/02/04(月) 23:30:10 ]
- 開発効率と現状溢れかえってるPCのスペックの話だろうか
まあ例外は確かに往々にあるけど例外は圧倒的にマイノリティ うちも業務じゃC/C++なんて使わないわ
- 322 名前:デフォルトの名無しさん mailto:sage [2008/02/05(火) 00:05:18 ]
- 何言ってんだこいつ。
Webでもやってろ。
- 323 名前:デフォルトの名無しさん mailto:sage [2008/02/05(火) 00:09:41 ]
- webは全然分類違うだろ、どこのアマグラマだよ
- 324 名前:デフォルトの名無しさん mailto:sage [2008/02/05(火) 00:10:33 ]
- 業務でC++主流だと思ってるのか・・
- 325 名前:デフォルトの名無しさん mailto:sage [2008/02/05(火) 00:14:07 ]
- マジョリティマイノリティでわけちゃうとなぁ
まあ業務になると大抵どっちかだけ向いてればいいんだが
- 326 名前:デフォルトの名無しさん mailto:sage [2008/02/05(火) 00:46:26 ]
- スレチ自重
- 327 名前:デフォルトの名無しさん mailto:sage [2008/02/06(水) 20:32:36 ]
- ここに適当なコード張ってみんなで最適化とか考えたけど適当な長さのコードが見当たらなくて10分で諦めた
- 328 名前:デフォルトの名無しさん [2008/02/07(木) 16:30:40 ]
- AMD向けの最適化に関するマニュアルはAMDのホームページにありますが、インテル用のはどこかでダウンロードできなうのでしょうか?
- 329 名前:デフォルトの名無しさん mailto:sage [2008/02/07(木) 16:42:36 ]
- >>328
www.intel.co.jp/jp/download/index.htm
- 330 名前:デフォルトの名無しさん mailto:sage [2008/02/09(土) 12:32:52 ]
- >>328
ttp://www.agner.org/optimize/
- 331 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 03:01:18 ]
- おいお前ら、俺のこいつをみてどう思う?
class Vector3 { public: union { struct {float x, y, z;} float data[3]; }; Vector3() {} Vector3(float ix, float iy, float iz) { x = ix; y = iy; z = iz; } }; inline Vector3 operator+(const Vector3 & va, const Vector3 & vb) { return Vector3(va.x + vb.x, va.y + vb.y, va.z + vb.z); } ベクトル化されるかな
- 332 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 03:16:06 ]
- 人に読んでもらうんならもうちょっとマシなコードを書いて欲しい所
- 333 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 03:17:37 ]
- 横レスだが、別に普通じゃねえかw
- 334 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 03:50:50 ]
- 全角スペースでいいからインデントをだな
- 335 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 03:51:35 ]
- コードがマシかどうかとは関係ないじゃん
- 336 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 03:52:06 ]
- >>332
「もうちょっとマシなコード」をkwsk
- 337 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 03:52:14 ]
- >>334だけど>>332じゃないです
- 338 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 03:52:45 ]
- ここで一つ自演を見付けると
- 339 名前:331 mailto:sage [2008/02/11(月) 04:00:14 ]
- 分かった、インデントが無いのは謝る
コンパイラ通してないのも謝る ただ俺は…ベクトル化について語って欲しかっただけなんだ…
- 340 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 04:03:30 ]
- コンパイルしてみりゃいいじゃん。
- 341 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 04:30:20 ]
- >>336
・classじゃなくて別にstructでいいんじゃ? ・無名共同体内無名構造体の後のセミコロンがない ・デフォルトコンストラクタ邪魔 ・メンバ初期化子を使って欲しい そして出来れば引数もconst type&で受け取った方が ・演算子オーバーロードを行う関数の引数名はrhs, lhsにするのが普通
- 342 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 05:04:44 ]
- >>341
・classじゃなくて別にstructでいいんじゃ? 俺は変数だけならstruct、関数あるならclass使ってるが ・無名共同体内無名構造体の後のセミコロンがない struct {float x, y, z;} ←これか。スマン ・デフォルトコンストラクタ邪魔 コンパイラによっては0で初期化される・・・っていう記憶があるから、 不定値のままでいいから一応書いた メンバ初期化子を使って欲しい そして出来れば引数もconst type&で受け取った方が うぉ?!全くその通りだw Vector3(const float & ix, const float & iy, const float & iz) : x(ix), y(iy), z(iz) {} これでおk? ・演算子オーバーロードを行う関数の引数名はrhs, lhsにするのが普通 知らんかった レスありがとう
- 343 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 05:22:15 ]
- 忘れるところだった。俺はベクt(ryについて聞いてたんだ
return Vector3(va.x + vb.x, va.y + vb.y, va.z + vb.z); こいつはベクトル化されるのか? それとも、 Vector3 v; for (int i = 0; i < 3; i++) {v.data[i] = lhs.data[i] + rhs.data[i];} return v; とか書かないとダメかな まぁコンパイラ依存な訳だが、どこまで美味く最適化してくれるか知りたいんだ
- 344 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 05:27:03 ]
- そこだけ見てもベクタ化されるかどうかは不明。
ってことで、クラスの作りだけ見ると、unionにする理由が判らん。 配列のようにも構造体のようにも使いたいのならそういうアクセッサを用意すればいいだけだから、 そもそもデータメンバを公開する理由が判らん。 あーそれから、floatを引き数とするコンストラクタなら参照にしなくて充分。
- 345 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 05:29:19 ]
- >>343
だから、コンパイラが何か、どんな使い方をするかなども書かれていないのにベクタ化されるかは不明だってば。 わざわざforループにしなくても、ベクタ化できるコンパイラならベクタ化すべきときにはしてくれるだろうよ。
- 346 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 05:48:14 ]
- これは3次元ベクトルのクラス。できる限りの高速化が望まれる
xyz公開してるのはGetX()とか作ったり使ったりするのが面倒くさいからだ コンパイラはVisual Stdio 2005のやつ
- 347 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 06:15:07 ]
- 「できる限りの高速化」を望みつつ、条件も出さずに実測もしないで、
挙句の果てに「面倒くさい」って、阿呆ですか?
- 348 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 07:07:04 ]
- >>347
俺が求めてるのは実測とかじゃなくて、最適化についての経験談なんだが こうした方がベクトル化され易い、とか… あと、 void Vector3::GetX() const {return x;} void Vector3::GetY() const {return y;} void Vector3::GetZ() const {return z;} とか実装しろと? 最適化、いや高速化に関係するのか?
- 349 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 07:42:43 ]
- >>348
だから、いろんなサンプル作って実測してみろって。 クラスを作るのなら効率よく組めて且つ速いものも狙うのは当然だろうし、 そうでないなら速度重視でがりがり書くことになるからクラスなんて作る意味がないって。 要は、やることが半端なの。
- 350 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 10:17:11 ]
- float を参照渡しする意味はあるのか?
- 351 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 10:21:53 ]
- >>349
自己矛盾乙
- 352 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 10:28:39 ]
- むしろだめだろう、リテラルわたせないじゃないか
- 353 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 10:36:13 ]
- 一時オブジェクトが生成されるから問題ない。
- 354 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 10:37:31 ]
- インライン化されるだろうから多分変わりはないだろうが、
積極的に参照にする理由は無いな。
- 355 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 10:39:02 ]
- そうでしたかごめんなさい
- 356 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 10:43:56 ]
- >>351
どこが自己矛盾?
- 357 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 11:55:47 ]
- 他人に訊く暇があったらまずやってみろ!
それで自分の力だけではどうにもならない事が起きた時初めて他人を頼る でないといつまでたっても他人に頼る癖が抜けないぞ
- 358 名前:デフォルトの名無しさん mailto:sage [2008/02/11(月) 11:56:22 ]
- インライン化される事を前提としているならconst参照渡しは問題ないというかコンパイラの助けにある程度なるだろうけど、
確かに中途半端に長い関数で1ワードごときの変数を参照にする必要は無い。
- 359 名前:デフォルトの名無しさん mailto:sage [2008/02/12(火) 02:45:14 ]
- >>357
ここは相談の場でなくて語り合う場だが?
- 360 名前:デフォルトの名無しさん mailto:sage [2008/02/12(火) 04:43:20 ]
- void float Func(const float &f)
{ return (f + f - f) * f / f; } イコール void float Func(const float *f) { return (*f + *f - *f) * (*f) / *f } だと思ってた。それとも void float Func(const float *f) { float g = f; return (g + g - g) * g / g; } こうか?参照渡しって内部的にどういう処理が行われてるの
- 361 名前:デフォルトの名無しさん mailto:sage [2008/02/12(火) 08:03:41 ]
- >>360
最適化されると、後2者の区別はなくなりますが。 # void float とかfloat g = f は兎も角
- 362 名前:デフォルトの名無しさん mailto:sage [2008/02/12(火) 11:12:40 ]
- >>360
最適化されると、内部的に変数の所在を渡すよりも変数の値をそのまま渡した方が速度が出るので void float Func(const float f) { return (f + f - f) * f / f; } になる。
- 363 名前:デフォルトの名無しさん mailto:sage [2008/02/12(火) 11:26:12 ]
- 適当にコピペして解説したんだけど
>void float まさかこんな風に書いてあったなんて
- 364 名前:デフォルトの名無しさん mailto:sage [2008/02/12(火) 11:27:45 ]
- >>362
最早意味不明だし。インライン展開されない限り、参照やポインタ渡しが値渡しになることは有り得ません。 # インライン展開されたらされたで、Func()自体が(その呼び出しについては)消えてなくなるだろうけど。
- 365 名前:デフォルトの名無しさん mailto:sage [2008/02/12(火) 11:41:48 ]
- >>364
不動小数点数の演算って、足して引いて 0 とか、かけて割って 1 とか、畳んでいいんだっけ?
- 366 名前:デフォルトの名無しさん mailto:sage [2008/02/12(火) 11:44:28 ]
- >>365
実際に最適化されるときに、引き数が明らかなら可能。 そういう意味では、>364は不正解。
- 367 名前:364 mailto:sage [2008/02/12(火) 12:05:54 ]
- >実際に最適化されるときに、引き数が明らかなら可能。
あー失礼しました。 gccでの確認ですが、確かにFunc(1.2f)とかは消えてなくなるけど Func(atof(argv[1]))とかだとちゃんと四則演算してますね。 -- call __strtod_internal fstps -4(%ebp) movss -4(%ebp), %xmm3 movss %xmm3, %xmm1 addss %xmm3, %xmm1 subss %xmm3, %xmm1 mulss %xmm3, %xmm1 divss %xmm3, %xmm1 subl $8, %esp cvtss2sd %xmm1, %xmm0 movsd %xmm0, (%esp)
- 368 名前:デフォルトの名無しさん mailto:sage [2008/02/14(木) 07:30:06 ]
- C/C++でGUIを実装する場合、どういった手段が適当でしょうか?(Windows環境)
色々調べてみたところ ・実際の職業プログラマさんなんかはC#やVB.NETみたいなのを使う ・WinAPIを直接、みたいなことは趣味でやる人が使う (山を登るのに、ロープウェイを使うのが賢いが趣味で山登りを楽しむ人がいるみたいな意味で) で、実際人に聞くと今度はMFCという意見が出てきました 調べるとWinAPIを糖衣したようなもののように感じたものの情報がすごく少ない と、こんな感じでして、どっちに進むべきか悩んでいます やりたいのはどっちだ、というのは手段と目的がryってやつでGUIの実装の手段をどうしたものか、という質問です C#/VB.NETというものも一応考慮のうちに入れておきたいです (GUIの実装はC/C++の枠を超えればそれがベターだから、という意見も考慮したいからです) それではよろしくお願いします
- 369 名前:デフォルトの名無しさん mailto:sage [2008/02/14(木) 07:56:45 ]
- スレタイ読め
- 370 名前:360 mailto:sage [2008/02/14(木) 09:34:39 ]
- スマン、遅レスだがvoidは間違いだ
floatもマズかったかな double Func(const double &d) { return (d + d - d) * d / d; } こいつはコンパイルされた後ってどうなるんだ? アセンブリ知らないから、とりあえずCの文法的に書いてみるけど double Func(double d) { return (d + d - d) * d / d; } になるのか。それとも double Func(double *d) { return (*d + *d - *d) * (*d) / *d; } になるのか。まさか後者みたいなコード吐かないよね もちFunc関数自体が省略されない場合で
- 371 名前:デフォルトの名無しさん mailto:sage [2008/02/14(木) 09:45:00 ]
- >>370
アセンブリ知らないという見方なら C の規格上の実行モデルで考えることになり、 その場合にはそれら2つは引数が値渡しである点を除いてほぼ等価。 違いを知りたければアセンブリを見るしかないでしょ。
- 372 名前:デフォルトの名無しさん mailto:sage [2008/02/14(木) 09:46:13 ]
- コンパイルして逆アセンブルしてみればいいんじゃないの?
- 373 名前:368 mailto:sage [2008/02/14(木) 10:34:16 ]
- すんませんごばく
- 374 名前:デフォルトの名無しさん mailto:sage [2008/02/14(木) 11:38:12 ]
- >>370
参照で書かれた関数は、ポインタで書かれた関数と同じコードを吐くよ。 その例では、後者と同じと言うことになる。 勿論、後者自体がdouble Func(double * d) {double tmp = * d; return (tmp + tmp - tmp) * tmp / tmp;} と殆んど同じコードを吐くという前堤でね。
- 375 名前:デフォルトの名無しさん mailto:sage [2008/02/14(木) 12:36:36 ]
- ちょっとコンパイルしてみた。
-- double func(double const d) {return (d + d - d) * d / d;} double func(double const & d) {return (d + d - d) * d / d;} double func(double const * d) {return (* d + * d - * d) * * d / * d;} double func(double const * d) {double tmp = * d; return (tmp + tmp - tmp) * tmp / tmp;} -- 以下適当に行を圧縮 _Z4funcd: movapd %xmm0, %xmm1 addsd %xmm0, %xmm1 subsd %xmm0, %xmm1 mulsd %xmm0, %xmm1 divsd %xmm0, %xmm1 movapd %xmm1, %xmm0 ret _Z4funcRKd: movsd (%rdi), %xmm1 movapd %xmm1, %xmm0 addsd %xmm1, %xmm0 subsd %xmm1, %xmm0 mulsd %xmm1, %xmm0 divsd %xmm1, %xmm0 ret _Z4funcPKd: movsd (%rdi), %xmm1 movapd %xmm1, %xmm0 addsd %xmm1, %xmm0 subsd %xmm1, %xmm0 mulsd %xmm1, %xmm0 divsd %xmm1, %xmm0 ret _Z4funcPKd: movsd (%rdi), %xmm1 movapd %xmm1, %xmm0 addsd %xmm1, %xmm0 subsd %xmm1, %xmm0 mulsd %xmm1, %xmm0 divsd %xmm1, %xmm0 ret
- 376 名前:デフォルトの名無しさん mailto:sage [2008/02/14(木) 14:55:14 ]
- >>375
VC++2003で最適化オプションを全て有効にして、その4つの関数を定義して 連続で呼び出してみたら、インライン展開されて計算は1回だけで結果を 4回コピーするだけのコードになった。完全に同一とみなされてるね。 あと、インライン展開されてないコードではSSEを使っているけど、展開された 部分ではSSEは使ってなかったな。
- 377 名前:360 mailto:sage [2008/02/16(土) 01:27:08 ]
- 俺の環境(VS2005SE)で速度重視ならこんな感じ
展開はされてない func1: fld qword ptr [esp+4] fld st(0) fadd st,st(1) fsub st,st(1) fmul st,st(1) fdivrp st(1),st ret func2: fld qword ptr [eax] fadd st(0),st fsub qword ptr [eax] fmul qword ptr [eax] fdiv qword ptr [eax] ret func3: fld qword ptr [eax] fadd st(0),st fsub qword ptr [eax] fmul qword ptr [eax] fdiv qword ptr [eax] ret func4: fld qword ptr [eax] fld st(0) fadd st,st(1) fsub st,st(1) fmul st,st(1) fdivrp st(1),st ret あれ、これってSSE使われてないよね。なんで?
- 378 名前:デフォルトの名無しさん mailto:sage [2008/02/16(土) 23:17:22 ]
- >>370
参照はポインタで渡されるので、関数を呼び出す場合は後者の関数が生成される。 インライン展開されるばあいは、最適化されてポインタが使われない前者と同等になるよ。 >>376 2005proではインライン展開もSSE2になってた。 >>377 SSE2のオプションは確認した?
- 379 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 09:22:53 ]
- >>378サンクス。オプション忘れてたw
インライン展開されているものは全て同じコード吐いてるっぽい されていないものはこんな感じ double func1(double const d) {return (d + d - d) * d / d;} 004018A0 movapd xmm0,xmm1 004018A4 addsd xmm0,xmm1 004018A8 subsd xmm0,xmm1 004018AC mulsd xmm0,xmm1 004018B0 divsd xmm0,xmm1 004018B4 ret double func2(double const & d) {return (d + d - d) * d / d;} double func3(double const * d) {return (* d + * d - * d) * * d / * d;} double func4(double const * d) {double tmp = * d; return (tmp + tmp - tmp) * tmp / tmp;} 00401880 movsd xmm1,mmword ptr [eax] 00401884 movapd xmm0,xmm1 00401888 addsd xmm0,xmm1 0040188C subsd xmm0,xmm1 00401890 mulsd xmm0,xmm1 00401894 divsd xmm0,xmm1 00401898 ret func1の方が短い事にちょっぴり驚いた。引数でdoubleそのまま使うのも有りって事か?
- 380 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 11:18:29 ]
- このスレに来て学んだことは「とりあえず素直に書いておけ」
- 381 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 12:34:23 ]
- 結局、最適化器を書いてるのは人間だから、
「彼らが想定する人間であること」 が大事になってくるわな。
- 382 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 18:45:37 ]
- double を参照渡しはまずせんわな。
- 383 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 20:55:13 ]
- たしかに直接にdoubleを参照渡しにすることは無いけど、テンプレートを使うときに引数を参照渡しにすることはよくある。
その結果、doubleを参照渡しにしてしまうことも多々ある。インライン展開なら参照渡しもしっかり最適化されるので助かる。コンパイラ屋さんに感謝だな。
- 384 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 21:59:07 ]
- 値渡し用の型を取得するためのテンプレート使うといいよ。
- 385 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 21:59:30 ]
- 値渡し用の型、じゃねえや。
そういった引数用の型、だ。
- 386 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 22:01:08 ]
- テンプレートだと、問答無用に値渡ししないか?
と思ったが、bindとかfunctionとか参照渡しだったな。
- 387 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 22:04:48 ]
- 特定の基本型のみ値渡しにし、
他の型は全部 const 参照にするってやつ。 要するに boost::call_traits<T>::param_type 。
- 388 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 23:13:07 ]
- 凄いことができるんだな。テンプレートって奥が深いな
- 389 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 23:15:22 ]
- つかフツウやるやろ
- 390 名前:デフォルトの名無しさん mailto:sage [2008/02/17(日) 23:16:53 ]
- まあ実装はかなり泥臭いがな。
基本的に const 参照にして、基本型全部で特殊化。 実際にはもうちょっと階層的に作ってあるけど、 基本的にはそんなとこ。
- 391 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 03:33:06 ]
- 分かりやすいのが一番だと思ってる。でも必要な所はあるわけですよ
・・・このスレに何しに来たっけ これをどうするか聞きに来たんだっけかw //---------- class Vector4 { public: float x, y, z, w; Vector4(float ix, float iy, float iz, float iw) : x(ix), y(iy), z(iz), w(iw) {} }; void Add(Vector4 * pO, const Vector4 & iA, const Vector4 & iB) { pO->x = iA.x + iB.x; pO->y = iA.y + iB.y; pO->z = iA.z + iB.z; pO->w = iA.w + iB.w; } //---------- ベクトル和を計算するAdd関数がある訳だが、とにかく速度が欲しい。 SSEのパックド単精度実数関連の命令(ADDPSとか)使えば早くなるはずだと というか、最適化で勝手にやってくれると思っていたんだが、パックド使ってるようには見えない まさか、この程度なら使わない方が早いのか・・・ おまいらならどうコーディングする? 完全にぶりかえしですまん
- 392 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 04:02:10 ]
- コンパイラが場合によって速いほうを選べるように inline にする。
必要な箇所があれば intrinsic でもアセンブラでも使う。
- 393 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/02/18(月) 04:26:20 ]
- 残念だがそれをaddps1個に翻訳できるほど現時点でのコンパイラは賢くない。だからこそのIntrinsicsなわけで。
|

|