1

全て、

PIC18 ボードの制御ループの一部であるため、1 秒間に何度も呼び出される C 関数があります。これらの関数にはメソッド スコープのみが必要な変数がありますが、これらの変数を常に割り当てることと、グローバルまたは少なくともより高いスコープの変数を使用することのオーバーヘッドがあるとしたらどうでしょうか。(パフォーマンスがメソッドのローカル変数を使用しないことを決定する場合、グローバル変数の使用を避けるために、より高いスコープから渡されるように構造体を typedef することを考えました)

ここには、このトピックをカバーするいくつかの優れたスレッドがありますが、決定的な答えはまだ見ていません。ほとんどの場合、ベスト プラクティスを説いており、マイクロ秒ごとにパフォーマンスが向上しない限り、これに従うことに同意します。

1 つのスレッドで、グローバル変数の代わりにファイル スコープの静的変数を使用することが言及されていましたが、それが必要なのか疑問に思わずにはいられません。

みんなどう思う?

4

3 に答える 3

2

ローカル変数にアクセスするには (スタック ポインターは*(SP + offset)どこにある) のようなことを行う必要がありますが、静的 (グローバルを含む) にアクセスするには のようなことが必要です。SP*(address)

私の記憶では、PIC 命令セットのアドレッシング モードは非常に限られています。そのため、少なくとも初めてアクセスする場合は、グローバルへのアクセスが高速になる可能性が非常に高くなります。コンパイラが計算されたアドレスをレジスタに保持している場合、後続のアクセスは同一である可能性があります。

@unwind がコメントで述べたように、コンパイラの出力とプロファイルを見て確認する必要があります。プログラムの実行時間の点で価値があることが証明された場合にのみ、明快さ/保守性を犠牲にします。

于 2012-02-07T15:23:43.823 に答える
1

現存するすべての PIC コンパイラを使用したわけではありませんが、2 つのスタイルがあります。私が使用したスタイルは、プログラムの呼び出しグラフを分析することによって、すべてのローカル変数を静的に割り当てます。すべての可能な呼び出しが実際に実行された場合、ローカルによって消費されるスタック メモリの量は、いくつかの注意事項 (HiTech の PICC-18 "標準" コンパイラの動作を説明します。他のものは異なる場合があります)

  1. 可変個引数関数は、 callerのスコープでローカル変数ストレージを定義し、そのストレージへの 2 バイト ポインターを呼び出される関数に渡すことによって処理されます。
  2. 間接関数ポインターのさまざまなシグネチャごとに、コンパイラーはコールグラフに「疑似関数」を生成します。その署名の関数を呼び出すものはすべて疑似関数を呼び出し、その疑似関数は、そのアドレスが取得されたその署名を持つすべての関数を呼び出します。

このスタイルのコンパイラでは、ローカル変数への連続アクセスは、グローバル変数への連続アクセスと同じくらい高速です。ただし、合計で 64 ~ 128 バイト (PIC のモデルによって異なります) を超えてはならない「near」として明示的に宣言されたグローバル変数と静的変数を除き、各モジュールのグローバル変数と静的変数は、ローカル変数とは別に配置されます。また、異なるバンクにあるものにアクセスするには、バンク切り替え命令が必要です。

私が使用していない一部のコンパイラは、「拡張命令セット」オプションを採用しています。このオプションは、「近い」バンクの 96 バイト (または 96 バイト未満の PIC ではそのすべて) を飲み込み、それを使用して FSR2 レジスタに関連する 96 バイトにアクセスします。最初の 16 バイト、または 32 バイトをスタック フレームとして使用する場合、これは素晴らしいコンセプトです。96 バイトを使用するということは、「近い」ストレージをすべて放棄することを意味し、これはかなり厳しい制限です。それにもかかわらず、この命令セットを使用するコンパイラは、スタック上のローカル変数に、グローバル変数と同じくらい高速ではないにしても、アクセスできます (バンク切り替えは必要ありません)。Microchip がスタック フレーム用に 16 バイト程度だけを確保して、「共通バンク」RAM の有用な量を残すオプションがあればいいのにと思いますが、それでも一部の人々はそのモードで幸運に恵まれています。

于 2012-02-07T16:28:11.167 に答える
0

これは、使用しているコンパイラに大きく依存すると思います。PICはわかりませんが、一部の(すべて?)PICコンパイラがコードを最適化して、ローカル変数が可能な限りCPUレジスタに格納されるようにすることを推測しています。その場合、ローカル変数はグローバル変数と同じくらい高速になる可能性があります。

そうしないと、ローカル変数がスタックに割り当てられている場合、グローバルへのアクセスが少し速くなる可能性があります(Oliの回答を参照)。

于 2012-02-07T15:46:17.397 に答える