[表示 : 全て 最新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/


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なわけで。

394 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/02/18(月) 06:37:36 ]
//----------
#include <dvec.h>
class Vector4 : public F32vec4
{
public:
 Vector4(float ix, float iy, float iz, float iw)
  : vec(ix, iy, iz, iw)
 {}
};

void Add(Vector4 * pO, const Vector4 & iA, const Vector4 & iB)
{
 *pO = iA + iB;
}

この程度だとラップする意味が無い

395 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/02/18(月) 06:40:31 ]
Intel C++ or VC++なら
#include <fvec.h>

でF32vec4を使う。
テキトーにラップしてよし。
あと、インライン化しないとあんまり効果ないよ。
実関数化するとコールのオーバーヘッドに食われる




396 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/02/18(月) 06:41:40 ]
class Vector4 : public F32vec4
{
public:
 Vector4(float ix, float iy, float iz, float iw)
  : F32vec4(ix, iy, iz, iw)
 {}
};

に訂正

397 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 08:29:40 ]
ダンゴさんの連投でスレが活気付いたな

398 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 08:38:46 ]
活気づいたっていうのかよこれは

399 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 10:24:21 ]
1人だけで盛り上がっていては活気付いたとはいえない。
実際に活気付くのは397からだから397の話題振りで活気付いたということにしないと。

400 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 12:34:36 ]
>>391
こうならばどうか?
//----------
class Vector4
{
private:
 float x, y, z, w;
public:
 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;
}
//或いは
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;
}


401 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 12:36:08 ]
>>400
最後の行に括弧が抜けてた。
};


402 名前:ヽ・´∀`・,,)っ¬ mailto:OH MY LITTLE バール♪ sage [2008/02/18(月) 15:42:20 ]
駄目。それでもスカラにしかならない。

addpsに展開されることが目的なら、配列にして
for(int i=0; i<4; i++) vD[i] = vA[i] + vB[i];

全要素に同じ操作をしてますよってヒントにはループが一番効果的。
手動アンロールしちゃうと効果ない。


403 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 15:57:21 ]
それバールだったのか。釣竿だと思ってたぜ。

404 名前:デフォルトの名無しさん mailto:sage [2008/02/18(月) 16:10:23 ]
内部をバラの変数にしても配列にしても外からはわからない。
これぞクラスで隠蔽する良さだな。

405 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 03:27:11 ]
遅レスすまん
f・・・vec.h・・・?こんなの知らなかったよ。
fvec.h は実数、dvec. h は整数の CPU 拡張機能を用いた演算関連のヘッダー、でいいのかな

class Vector4 : public F32vec4
{
public:
 Vector4() {}
 Vector4(float ix, float iy, float iz, float iw) : F32vec4(ix, iy, iz, iw) {}
 Vector4 & operator =(const F32vec4 & rhs) {*this = rhs; return *this;}
};

inline void Add(Vector4 * pO, Vector4 & iA, Vector4 & iB)
{
 *pO = iA + iB;
}

inline void Normalize(Vector4 * pO, const Vector4 & i)
{
 F32vec4 v2(i * i);
 F32vec4 norm(sqrt(v2[0] + v2[1] + v2[2] + v2[3]));
 *pO = i / norm;
}

正規化関数も作ってみた。俺の理解力だと今はこれが限界
Vector3 とかも作ってみたいが、float * 4 をパックにしなくちゃいかんから、float 1つ分余計にメモリ必要なんだな
fvec.h & dvec.h は xmmintrin.h をインクルードしてるが、直接使っても構わないかな

>>400
今まではそうしてた。あと、「};」が抜けてるからメンバ関数が inline か否か判らんぞ

追伸:Intrinsics の発音はイントリンシックスでおk?



406 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 04:22:14 ]
>>405
>\in-?trin-zik, -?trin(t)-sik\
>ttp://cougar.eb.com/soundc11/i/intrin01.wav
よって、「イントリンジク」。

407 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 11:33:11 ]
>>405
VC++なら
class Vector4
{
public:
 union {
  float d[4];
  struct { float x, y, z, w; };
 };
};
これでAddをforループにしたら、SSE使ってくれたよ。

408 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 12:23:05 ]
class myvec
{
public:
 union {
  T array[N];
  struct { T a, b, c, d, ... };
 };
};

とする場合、特にTがマシンが扱う1Wordの倍数でないと
元々struct { T a, b, c, d, ... }; 部分の各要素の連続性が保証されてないからどう動くかが分からなくなる。
つまり T array[N] では T はきっちり詰め込まれているものの、 struct { ... }; は中で要素の間に空白のブロックが入る可能性がある。
ふじこふじこ

409 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 13:09:07 ]
ごめん、407を訂正する。
SSE使っていることには使っているが
 movss xmm4, DWORD PTR [eax-8]
 addss xmm4, xmm0
 movss DWORD PTR [eax-8], xmm4
こんなコード吐いてた。(要素数の数だけ繰り返し)
VC++2003ではベクトル化してくれるほど頭よくないようだ。

これでも普通にFPU使うよりは速いの?

410 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 21:57:23 ]
>>407
クラスメンバの実体は

private:
float r[4];

にしといて、メンバ関数で

public:
float &x(){return r[0];};
const float &x()const{return r[0];};

などとするのがC++的。

411 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 21:58:16 ]
>>409
x86-64はSSE使う方が速いし、FPUの利用は推奨されていない。

412 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/02/19(火) 23:01:55 ]
自動ベクトル化は何故かVC++ではやってくれないね。何年もなるのに未だに対応しない。
まあIntrinsicsを使うのがいいでしょう。

どのみち配列にしちゃうと仮に運よくベクトル化できてもメモリアクセスが必ず発生しちゃうので
性能落ちる。F32vec4かもしくは__m128iから派生するのがヨシ。

413 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 01:49:02 ]
>>410
そういう仕様のベクトル演算クラスって少ないよ。C++でも

414 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/02/20(水) 02:11:33 ]
より汎用化したいならテンプレートにしてIntrinsicsベッタリな部分はtraitsで実装するとかいう手もあるわな

fvecやdvecはラッパークラスの実装サンプルだと思ってもいい。ちなみにSSE3〜4には対応してない。

415 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 05:15:43 ]
なるほど、実装サンプルね。じゃあdvecが参照してるヘッダを活用して
独自にラッパー作ってもいいわけだ

>どのみち配列にしちゃうと仮に運よくベクトル化できてもメモリアクセスが必ず発生しちゃうので
>性能落ちる
ここの意味がわかりませんぜ親分。うまくベクトル化できてもIntrinsics使ったコードには勝てないのか?



416 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/02/20(水) 06:12:03 ]
配列=かならずアドレスを持つ=レジスタ変数にできない。
いっぽうで__m128の実体はレジスタに割り当て可能。

レジスタ上に置いて演算を繰り返すような用途には、ロード・ストアは無駄。

417 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 11:56:09 ]
なんでバールの人はそんなに詳しいの

418 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 12:25:31 ]
>>416
> 配列=かならずアドレスを持つ=レジスタ変数にできない。

これってどんなコンパイラでもそうなっちゃうの?

419 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 12:53:19 ]
>>418
最適化によってずっとレジスタに保持するケースもあるとは思うが、
それでも一応メモリ領域に置くだけは置くようだ。

420 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 12:59:55 ]
>>419
へぇ。そんなこともあるんだ。

で、それは特定のコンパイラでの実験結果であて、規格上レジスタだけで
済ませることができない制約がある、というわけじゃないよね?

421 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 14:08:55 ]
でもC++はregister変数のアドレスを取れちゃうから不思議。

422 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 14:23:19 ]
ふと、メンバ変数も仮想関数もない空のクラスでも
アドレス取れないといけないからサイズ0にならないって話を
思い出した。

423 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 20:03:28 ]
>>421
register はコンパイラへのヒントであって
必ずレジスタに割り付けする必要はないからな


424 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 20:11:33 ]
>>423
それでもCだと文法エラーなんだよ
この辺が解せない

425 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:23:59 ]
>>424
でも本来の意味的にアドレス取れちゃおかしいよね。



426 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:25:16 ]
インライン関数のアドレスが取れるくらいだからいいんじゃね。

427 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 00:02:43 ]
ひょっとしてアドレスを取るコードを書いた時点でレジスタに入らなくなったりインライン化されなくなったりする?

428 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 00:06:35 ]
ローカル変数のスタック・レジスタへの割り当てについては
ダンゴさんが鋭い意見を持っていると思う

再利用とか

429 名前:ヽ・´∀`・,,)っ¬ mailto:OH MY LITTLE バール♪ sage [2008/02/21(木) 00:21:52 ]
CellのSPE用コンパイラはregisterキーワードつけただけでアドレスをとるコードはコンパイルエラー吐く。
レジスタが十分に多くレジスタ間オペレーション前提のアーキはこんなもんでしょ

430 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 00:24:55 ]
関数はアドレスとろうとどうしようと、インライン展開の妨げにはなりませんな。
なんせ、通常版を展開しておきさえすれば後は何でもありだから。
gccなんかだと、再帰関数でも一段目だけインライン展開してたりして楽しい。

431 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 12:29:10 ]
>>427
アドレス取る可能性があると、最適化の掛かりが悪くなるな気がする。がっちりprivateで包んで、メンバ変数のポインタを外から取れなくすると効果ある様な気がする。


432 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 12:36:29 ]
>>427
メンバ変数はすでに this でアドレス取られてるようなもんだろ。 private とか関係ないと
思うよ。

433 名前:432 mailto:sage [2008/02/21(木) 12:36:56 ]
アンカーミスった >432 は >>431 ね。

434 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/02/21(木) 23:21:34 ]
アクセス属性は最適化のかかりには関係ないです。
friend属性で完全に読めるしね。


なんにせよ「レジスタ型」のラッパークラスって扱いが難しいだろうな

fvecやdvec使ってても、各要素に配列インターフェイスでにアクセスしようとすると
いったんメモリ上にストアしてから各要素を読み出す動作になる。
なぜならそういう作りだから。
SSE4.1のextractps/dならレジスタ間渡しができるだろうけど。

435 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 15:32:37 ]
正直、クラスメンバはぶっちゃけグローバル変数なんで最適化かかりにくい。



436 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 21:23:32 ]
大分関係無いけどだんごさんのクロージャに対する意見を聞きたいです

437 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/02/22(金) 22:57:28 ]
変態boostはおなかいっぱい


438 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 23:41:48 ]
ダンゴさんは本当に知識豊富だな

439 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 01:18:13 ]
別に「変態boostはお腹一杯」では何も有益な事は読みとれんだろww
むしろ「もうこりごりだ」っていう反応にも取れるくらいだ。
C++のクロージャについてはgccなんかがサポートしてるから、アセンブラを吐かせてみて
そのコードを見るって言うのはどう?結構面白い実装になっていると聞いたことがある。

440 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 01:54:46 ]
439は本当に知識豊富だな


441 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 01:55:54 ]
クロージャ使うと遅くなるってイメージがある

442 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/02/23(土) 01:58:40 ]
っていうかboostってコードサイズをboostするんだよ。


443 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 02:06:44 ]
別に「別に\「変態boostはお腹一杯\」では何も有益な事は読みとれんだろww\
むしろ\「もうこりごりだ\」っていう反応にも取れるくらいだ。\
C++のクロージャについてはgccなんかがサポートしてるから、アセンブラを吐かせてみて\
そのコードを見るって言うのはどう?結構面白い実装になっていると聞いたことがある。」では何も有益な事は読みとれんだろww
むしろ「もうこりごりだ」っていう反応にも取れるくらいだ。
C++のクロージャについてはgccなんかがサポートしてるから、アセンブラを吐かせてみて
そのコードを見るって言うのはどう?結構面白い実装になっていると聞いたことがある。

444 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 02:07:24 ]
Boostつかうと一気に実行ファイルサイズが10倍に?!

445 名前:ヽ・´∀`・,,)っ━━━━━━┓ mailto:sage [2008/02/23(土) 02:08:11 ]
\7



446 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 02:09:10 ]
>>444
でも使わないと実行時に要するメモリサイズが10倍に!?

447 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 02:32:18 ]
boost使うとコンパイル時間が4倍位に

448 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 02:32:46 ]
それはリアルな

449 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 02:37:29 ]
boost――それは決して便利とは言えない、そして無駄にコンパイルの時間とファイルサイズだけを喰っていってしまう。
しかし必要とあれば使わなければならんのだ――漢にはそういう時が来るものなのだ。

450 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 09:51:43 ]
必要でもあえて使わないのが漢じゃねーのか?

451 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 09:59:07 ]
1クロック1バイトまでこだわった俺仕様ライブラリを作るのが漢ってものじゃないのか。


452 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 11:41:07 ]
昔, RAM 1k とかで 8bit マシンのアセンブラ書いて時は
メモリの 1byte は血の一滴って感じだったけどな…


453 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 11:50:57 ]
>>450
人、それを馬鹿と言う。

454 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 13:08:01 ]
>昔, RAM 1k とかで 8bit マシンのアセンブラ書いて時は
1024バイトなんて随分贅沢だなぁ、おい。

455 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 19:12:43 ]
いや、1Kbitじゃないか。




456 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 21:28:52 ]
6810か

457 名前:デフォルトの名無しさん mailto:sage [2008/02/24(日) 06:40:59 ]
>>456
それだったら4114x2の方が安いんじゃないだろうか?







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

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

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