変数には、静的 (グローバル)、スタック (自動)、およびレジスタの 3 つの大まかなクラスがあります。
レジスタ変数は、CPU レジスタに格納されます。レジスタは、CPU パイプラインに統合された非常に高速なワード サイズのメモリです。それらは無料でアクセスできますが、非常に限られた数しかありません (通常、プロセッサと実行している操作に応じて 8 から 32 の間です)。
スタック変数は、スタックと呼ばれる RAM の領域に格納されます。スタックはほとんど常にキャッシュにあるため、スタック変数は通常、アクセスに 1 ~ 4 サイクルかかります。
一般に、ローカル変数は、レジスターまたはスタックのいずれかに置くことができます。それらが関数の先頭に割り当てられているか、ループ内に割り当てられているかは問題ではありません。関数呼び出しごとに 1 回だけ割り当てられ、割り当ては基本的に自由です。コンパイラーは可能な限り変数をレジスターに入れますが、アクティブな変数がレジスターよりも多い場合、それらはすべて収まりません。また、変数のアドレスを取得する場合、レジスタにはアドレスがないため、スタックに格納する必要があります。
グローバル変数と静的変数は別物です。通常は頻繁にアクセスされるわけではないため、キャッシュに存在しない可能性があり、アクセスに数百サイクルかかる場合があります。また、コンパイラは事前にグローバル変数のアドレスを認識していない可能性があるため、ルックアップが必要になる場合がありますが、これもコストがかかります。
他の方もおっしゃっている通り、あまり気にしないでください。知っておくと良いことは間違いありませんが、プログラムの作成方法に影響を与えるべきではありません。意味のあるコードを記述し、コンパイラーに最適化について心配させます。コンパイラの開発に取り掛かると、それについて心配し始めることができます。:)
編集:割り当ての詳細:
レジスタ変数はコンパイラによって割り当てられるため、ランタイム コストは発生しません。コードは、値が生成されるとすぐにレジスタに値を入れます。
スタック変数は、実行時にプログラムによって割り当てられます。通常、関数が呼び出されると、最初にすべてのローカル変数用に十分なスタック スペースが確保されます。したがって、変数ごとのコストはありません。