• ベストアンサー

staticの動作について

C++で趣味でゲームを作っているのですが、staticを使ったときのローカル変数の動作について質問があります。 いまいち、ローカル変数の動作が分かっていないのですが、大雑把には、関数が読み出される毎に空いてるメモリを探して、そこを確保する物だと思ってます。 で、staticを用いて宣言すると内容が保持されると言うことは、これは始めに一回だけメモリの確保をして、以降はそれを継続して使っているというものなのでしょうか? だとすると、staticをつかったローカル変数の方が、繰り返しメモリの確保が行われ無い分、処理が早いということでしょうか? いま、ゲーム内では、描画用の関数描画基準座標とサイズを受け渡して入るのですが、どうしても内部で描画終了点と開始点のクリップを計算する必要があり、そのためにどうしても計算した開始点、終了点を保持する変数が必要になっています。 しかし、描画関数はキャラの分と背景描画の分とパーティクルの描画の分と、ゲーム1ループないでも1000回近く(多いときは2000回ぐらい)呼び出されてます。 その度にメモりの確保をされるのはなんか気分が悪いなぁと思ってstaticを何となくつているのですが、実際の所staticを着けたら動作がはやくなるとかと言うことは無いのでしょうか? 宜しくおねがします。

質問者が選んだベストアンサー

  • ベストアンサー
  • Interest
  • ベストアンサー率31% (207/659)
回答No.2

メモリの構造について理解すると、static をつけるとどうなるか理解できると思います。 プログラムのメモリは大雑把に分けると次の4つの領域(セクション)から構成されます。 (a) 実行コード領域 (b) データ領域 (c) スタック領域 (d) ヒープ領域 (a)実行コード領域と(b)データ領域の中身は名前の通りで、一度メモリ上に確保されるとその場所はずっと変わりません。外部変数はデータ領域に確保されます。 (c) スタック領域はローカル変数や関数の引数、関数の呼び出し元へのリンクなどに使用されます。再帰関数を使用するとあっという間にスタックが消費されて溢れてしまい、スタックオーバーフローを起こすことがあります。 (d) ヒープ領域はC言語ならmalloc/calloc、C++ならnewを使ってメモリを確保する場合に使用される領域です。new して確保した領域を deleteしない処理を繰り返すと、使用可能なヒープ領域がだんだん減っていき、メモリリークが発生します。 さて、staticを使ったローカル変数ですがこれはスタック領域ではなくデータ領域に確保されます。というのは、staticなローカル変数をヒープ領域に確保してしまうと、その関数を抜けたらローカル変数に割り当てたメモリを返却しなければいけなくなり、値を保持できなくなるからです。 > staticを用いて宣言すると内容が保持されると言うことは、 > これは始めに一回だけメモリの確保をして、以降はそれを継続 > して使っているというものなのでしょうか? その通りです。データ領域に確保して、継続して使っています。 > だとすると、staticをつかったローカル変数の方が、 > 繰り返しメモリの確保が行われ無い分、処理が早い > ということでしょうか? いいえ、そのようなことはありません。パソコンの場合、CPUがプログラムを動かすために使用するメモリは高速な順に次のようになっています。 (1) CPU内部のレジスタ (2) CPU内部のキャッシュメモリ(1次キャッシュ、2次キャッシュ) (3) DDR-SDRAMなどの主記憶 CPUのコアはプログラムを実行するのに直接主記憶(ここではDDR-SDRAM)にアクセスすることができず、CPU内部のレジスタに命令やデータをロードしてから次に実行すべき処理を判断します。このCPU内部のレジスタは非常に高速(※1)ですが、レジスタの数は非常に少なく(※1)、多くの命令やデータを保持することができません。 ※1 CPUのコアと同じ速度で動作する。 ※2 PowerPCなど一般的な32bit RISC CPUでは32bit×32個程度、インテルのIA-64アーキテクチャ CPUの場合は 128個程度。 CPUコアに対して主記憶は非常に遅い(※3)ため、CPUと主記憶の間にキャッシュメモリを入れて、頻繁に使うものだけキャッシュに入れて速度差を補っています。 ※3 例えばCPUコアのクロックが3GHzに対して DDR2 SDRAMのクロックが800MHzなど。 以上を踏まえると、ローカル変数にstaticをつけてもつけなくても、CPU内部のレジスタから外に出てしまえば処理速度に差はありません。おそらく、コンパイラで最適化をかけると消えてしまう程度の差だと思います。

koutai
質問者

お礼

すいません返信が遅れてしまいました。 なるほど、コンパイラで最適化がかかれば消えてしまうほどのものなのであれば、staticはどうしても値を継続して使いたいときだけにした法が良いみたいですね。 すっきりしました。 ありがとうございました。

その他の回答 (1)

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.1

実際のところ、ほとんど違いはないですし、むしろ遅くなる可能性もあります。 staticなしのローカル変数(auto変数といいます)は多くの実装でスタック上に取られます。このスタックに取るというのは非常に高速なのです。 したがって、メモリの確保に要する時間はほとんどゼロで済みます。 また、最近(でもないか)のCPUではメモリキャッシュという仕組みがあります。 この仕組みのため、近いところに格納されているメモリをアクセスする分には高速でも、別のところに格納されているメモリをアクセスする際に速度が低下する場合があります。staticをつけると別のメモリに格納されるため、かえって遅くなる可能性があります。といっても、ほんのわずかでしょうが。 こういった疑問が生じた場合は実際に速度を測定してみるといいですよ。

koutai
質問者

お礼

ご回答ありがとうございます。 むしろ遅くなってしまうこともあるのですか...。 なるほど、早速不必要なstaticをはずさなければなりませんね。(苦笑) 今度から自分でも速度を測定してみます。

関連するQ&A