5

以下のコードがあるとしましょう:

int led = 13;

void setup() {                
  pinMode(led, OUTPUT);     
}

void loop() {
  ledChange(HIGH);
  delay(1000);
  ledChange(LOW);
  delay(1000);
}

void ledChange(int pinState)  {
  digitalWrite(led, pinState);
}

digitalWrite(led, pinState);独自の関数への移行は処理時間に影響しますか?

もちろん、単一の LED ではパフォーマンスは重要ではありませんが、すべてのクロック サイクルが重要な場合 (高いサンプリング レート、ループ内の多くの演算など) は問題になる可能性があります。

4

3 に答える 3

8

void として定義されている関数は、関数から期待される戻り値がないことをコンパイラ/オプティマイザに通知するだけです。

したがって、戻り値を保存または操作するためのコードは生成されません。

これは Arduino 固有のものではなく、一般的な C の動作です。

于 2013-04-10T22:49:55.237 に答える
8

はい、わずかな量のクロック サイクルを無駄にしています。を書き込むledChange(LOW)と、CALL タイプの命令にコンパイルされます (プログラム カウンター レジスタにメソッドの場所にジャンプするように指示します)。

したがって、これは基本的に次のようにコンパイルされます。

  • いくつLOWかのレジスタまたはスタックに入れます
  • の場所にジャンプledChange()
  • メモリからフェッチし、どこかledに一緒に置きますLOW
  • にジャンプdigitalWrite()
  • 入っているものは何でもするdigitalWrite()
  • ジャンプバック
  • ジャンプバック

CALLジャンプは、スタックをいじることが多く、通常のJMP命令よりもはるかに時間がかかることに注意してください。

一方、単に実行すると、次のようにdigitalWrite(led,LOW)なります。

  • をメモリのどこかからフェッチしled、アクセス可能な場所に配置しますLOW
  • にジャンプditigalWrite()
  • 入っているものは何でもするdigitalWrite()
  • ジャンプバック

対応するコンパイル済みコードで引数がどのように渡されるかは完全にはわかりません。おそらく呼び出しの一部です。また、コンパイラはさまざまであり、一部のコンパイラは他のコンパイラよりも優れていることに注意してください。

関数のカプセル化により、プログラムを実行するたびに、プログラムがより多くのクロックサイクルを消費したことがわかります。ただし、これは最適化する価値はありません。このようなカプセル化には、Arduinoの速度を低下させるほどの容量はありません。その上、私が述べたように、一部のコンパイラはそのようなことを最適化します。


これは、関数が であることとは何の関係もありませんvoid。それが関数だった場合、戻り値の前に int を格納するにはor スタック操作が必要になるため (どれを忘れたか) int、処理速度が非常に遅くなります。MV

于 2013-04-11T04:55:09.590 に答える
2

アセンブリ出力を表示するように avr-gcc をセットアップできます。調べてみると、関数の戻り値の型はコードのサイズに関係ないことがわかります。値を返さない場合、余分なコードは生成されません。ただし、コンパイラの警告が表示されるためvoid、この場合に使用すると便利です。

関数を使用すると、コードが必要になるたびに関数内でコードを繰り返す必要がないため、コードが短くなる可能性があります (これは、呼び出しをオフセットして命令を返すために関数内に十分なコードが必要になることを意味します)。 -これはほとんどの場合です)。これにより、call 命令と return 命令を実行する必要があるため、コードが若干遅くなりますが、サイズの縮小とコード メンテナンスの改善によって相殺される可能性が高くなります。

私は十分に明確だったと思いますが、これは少し複雑に思えます:)

于 2013-04-11T01:24:18.240 に答える