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


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

203 名前:デフォルトの名無しさん mailto:sage [2007/10/20(土) 15:24:11 ]
>>200
質が悪いって言うけど、どの一部を取り出してもそういった偏りが全く無いほうが質が悪いでしょ。
固定の種にしたいなら好きなだけ選びなよ。

204 名前:デフォルトの名無しさん mailto:sage [2007/10/20(土) 15:28:19 ]
つーか擬似乱数スレでやれよ

205 名前:デフォルトの名無しさん mailto:sage [2007/10/20(土) 15:58:23 ]
sine、cosine

206 名前:デフォルトの名無しさん mailto:sage [2007/10/20(土) 17:18:59 ]
tangent

207 名前:デフォルトの名無しさん mailto:sage [2007/10/20(土) 19:44:18 ]
cosecant



208 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 00:53:23 ]
俺には >>200 の乱数列のどこが質が悪いのか分からん
誰か説明してくれ

209 名前:デフォルトの名無しさん [2007/10/21(日) 12:35:59 ]
>>208
このスレは馬鹿なお前のためにあるんじゃない

210 名前:デフォルトの名無しさん mailto:sage [2007/10/21(日) 19:33:52 ]
>>200

乱数の種で複数の値とるとき
互いに素ってのと2の累乗を自分は使わないようにしているけど…
根拠がない。それに小さすぎる値も使わないようにしている。(1とか2とか…)

211 名前:デフォルトの名無しさん mailto:sage [2007/10/23(火) 01:51:46 ]
>>200
void srand_xor128(void){ w^=(unsigned)time(0)*1812433253; }

とかwだけ変更すればたぶんおk。心配なら最初の十万個位捨てたら。


212 名前:デフォルトの名無しさん mailto:sage [2007/11/07(水) 04:00:14 ]
PSP用ゲームのVCとGCCの両用ソースなんですが
関数内でstaticな配列を使ってはならないという社内ルールが付けられているんですが
理由わかります?

void hoge()
{
static const int array[100] = { 123, 456, 789, 123, 456, 789, };
,,,,
}
このようなstaticは駄目で
const int array[100] = { 123, 456, 789, 123, 456, 789, };
にしろということなのです。
メモリが厳しいらしいのですが、これで本当に節約になるんでしょうか。

213 名前:デフォルトの名無しさん mailto:sage [2007/11/07(水) 04:34:13 ]
>>212
実際にコンパイルしてアセンブリ出力を眺めてみれば?
前者は静的領域に確保されることが保障されていて消えることは多分ないが、
後者は最適化で消える可能性がある。
しかし、後者は静的領域からスタックにコピーする最悪なコードになるかもしれない。

それはさておき、100要素指定しておいて6個しかないと激しく無駄だと思う。

214 名前:デフォルトの名無しさん mailto:sage [2007/11/07(水) 04:36:44 ]
>>212
メモリの節約にはならないだろう。

一般的な実装を予測すると、 static をはずしてもスタックに確保された配列を
初期化するためのコピー元となる配列が作られてしまう。この初期値の配列が
static をつけた場合に確保される実体と同等のはずなので、 static をはずすと
スタックの領域と初期化用コピーの処理時間が余計に増えるだけになる。

動作上の違いは、再帰呼び出ししたときに配列のアドレスが別物になるかどうか、
という点しかないはず。

はっきり言って逆効果だろう。そのルール決めた人に理由を問い詰めたほうがいい。

非 const な変数に限ってローカル static を禁止するのなら、メンテナンス性の観点から
まだ理解できる。

215 名前:デフォルトの名無しさん [2007/11/07(水) 04:56:45 ]
次に静的記憶域期間(static)です。

こちらは宣言されている場所にかかわらずプログラムの開始直前にメモリを確
保し初期化します。初期化を忘れた場合値は0になります。
また、確保された領域はプログラムが終了するまで保持されるので関数の終了
時に値が消えることがありません。2回目以降関数内のstaticオブジェクトを
利用するときは前回の値から始まります。


216 名前:デフォルトの名無しさん [2007/11/07(水) 05:00:13 ]
もっとも時間食っているところ、メモリ食っているところを押さえればよい
あとはいちいち細かいモジュールに制限加えることはない

217 名前:デフォルトの名無しさん mailto:sage [2007/11/07(水) 10:01:37 ]
>>212
逆(実際はstatic推奨)か、厳しいのはスタックか。



218 名前:デフォルトの名無しさん [2007/11/07(水) 10:40:48 ]
400バイトくらいで厳しいのかよ
2M = 2000000バイトくらいは使用できるんだろ? 400を繰り返し使ってメモリリークするとかなら
考慮するひつようあるだろうけど使用後に解放されるなら他のプログラムに影響しないと思うが
500K = 500000バイトくらい使うところから節約しろよ

219 名前:デフォルトの名無しさん mailto:sage [2007/11/07(水) 10:54:42 ]

for (int i=0;i<100;i++)
a[i]=b[i]*xx;

だと問題なくベクトル化されるのですが

for (int i=0;i<100;i++)
a[i]=a[i]*xx;

だと
 remark: loop was not vectorized: dereference too complex.
となってベクトル化されません。
自分自身が式の中に入っているとベクトル化できないのでしょうか?
コンパイラはicc ver 10で、OSはFedora 7です。

220 名前:デフォルトの名無しさん [2007/11/07(水) 11:05:35 ]
ベクトル化がわからない
配列に掛け算できないならコンパイラが壊れている

221 名前:デフォルトの名無しさん mailto:sage [2007/11/07(水) 11:08:34 ]
>>219
非常にシンプルなサンプルを作って試したら、どちらのケースもベクタ化できるようだよ。
配列aが何か特殊なことになってないかい?
再現できるソースは貼れないかな?

222 名前:212 mailto:sage [2007/11/07(水) 20:11:28 ]
ありがとうございました。
私は開発機でコンパイルする権限も無い下っ端なのですが、
腑に落ちなかったモヤモヤが少し晴れました。


223 名前:デフォルトの名無しさん [2007/11/10(土) 05:11:33 ]
ループを200回くらい繰り返すとき、全部展開しておいた方が速いですか
インライン展開とかも出来て
あと、1万回するときに100回と100個展開した方が良いですか?

224 名前:デフォルトの名無しさん mailto:sage [2007/11/10(土) 05:14:18 ]
>>223
余計なことせずにコンパイラに全て任せるのが正解だ。

225 名前:デフォルトの名無しさん mailto:sage [2007/11/10(土) 05:17:58 ]
基本がなってない奴は気にするだけ無駄

226 名前:デフォルトの名無しさん [2007/11/10(土) 06:01:10 ]
誰かいませんか!
助けてください!!

227 名前:デフォルトの名無しさん mailto:sage [2007/11/10(土) 06:04:49 ]
どうしたの



228 名前:デフォルトの名無しさん [2007/11/10(土) 06:08:40 ]
スレ違いかもしれませんが
C言語の宿題がわからなくてこまってます!

明日ってか今日までなんです〜
一緒に考えてくれる人いませんか?
お願い助けて〜

229 名前:デフォルトの名無しさん mailto:sage [2007/11/10(土) 06:28:53 ]
宿題スレで聞けば?






って既にマルチしてるな。






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

前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