답변:
setup () 및 loop ()를 수행하는 ATmega 코어의 코드 부분은 다음과 같습니다.
#include <Arduino.h>
int main(void)
{
init();
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}
매우 간단하지만 serialEventRun ()의 오버 헤드가 있습니다. 거기에.
두 가지 간단한 스케치를 비교해 보겠습니다.
void setup()
{
}
volatile uint8_t x;
void loop()
{
x = 1;
}
과
void setup()
{
}
volatile uint8_t x;
void loop()
{
while(true)
{
x = 1;
}
}
x와 volatile은 최적화되지 않도록하는 것입니다.
생성 된 ASM에서는 다른 결과가 나타납니다.
while (true)는 단지 몇 가지 명령을 rjmp (상대 점프)로 수행하는 반면 loop ()는 빼기, 비교 및 호출을 수행합니다. 이것은 4 명령 대 1 명령입니다.
위와 같이 ASM을 생성하려면 avr-objdump라는 도구를 사용해야합니다. 이것은 avr-gcc에 포함되어 있습니다. 위치는 OS에 따라 다르므로 이름별로 검색하는 것이 가장 쉽습니다.
avr-objdump는 .hex 파일에서 작동 할 수 있지만 원래 소스와 주석이 없습니다. 방금 코드를 빌드 한 경우이 데이터가 포함 된 .elf 파일이 생성됩니다. 이 파일의 위치는 OS에 따라 다릅니다. 파일을 찾는 가장 쉬운 방법은 환경 설정에서 상세 컴파일을 켜고 출력 파일이 저장되는 위치를 확인하는 것입니다.
다음과 같이 명령을 실행하십시오.
avr-objdump -S output.elf> asm.txt
그리고 텍스트 편집기에서 출력을 검사하십시오.
main.c
Arduino IDE에서 사용하는 표준의 일부이므로 절대로 꺼내지 않습니다 . 그러나 HardwareSerial 라이브러리가 스케치에 포함 된 것은 아닙니다. 실제로 사용하지 않으면 포함되지 않습니다 ( 기능 이 if (serialEventRun)
있는 이유 main()
입니다. HardwareSerial 라이브러리를 사용하지 않으면 serialEventRun
null이 발생하므로 호출이 없습니다.
Cybergibbons의 답변 은 어셈블리 코드 생성과 두 기술의 차이점을 잘 설명합니다. 이것은 실제적인 차이, 즉 두 접근 방식이 실행 시간 과 관련하여 얼마나 많은 차이를 보일지 에 대한 문제를 검토하는 보완적인 답변 입니다.
나는 한 분석을 다음과 같은 변화를 수반을 :
void loop()
(컴파일시 인라인 됨)void loop()
(을 사용하여 __attribute__ ((noinline))
)while(1)
(최적화)while(1)
(을 추가하여 __asm__ __volatile__("");
. 변수의 nop
추가 오버 헤드없이 루프의 최적화를 방지 하는 명령입니다 volatile
)void loop()
최적화 된 인라인while(1)
void loop()
최적화되지 않은 인라인while(1)
이러한 스케치를 각각 30 초 동안 실행하여 각각 300 개의 데이터 포인트 를 축적했습니다 . delay
각 루프마다 100 밀리 초의 호출 이있었습니다 (어떤 나쁜 일도 발생 하지 않음 ).
그런 다음 각 루프의 평균 실행 시간을 계산하고 각각에서 100 밀리 초를 뺀 다음 결과를 플로팅했습니다.
http://raw2.github.com/AsheeshR/Arduino-Loop-Analysis/master/Figures/timeplot.png
while(1)
루프 void loop
는 컴파일러 최적화보다 빠릅니다 void loop
.avr-gcc
Arduino IDE에 의존하지 않고 직접 최적화 플래그를 사용 하고 수동으로 컴파일하는 것이 좋습니다 (마이크로 초 최적화가 필요한 경우).
참고 : 실제 시간 값은 여기에서 중요하지 않습니다. 실행 시간의 ~ 90 마이크로 초에 대한 호출을 포함하고 Serial.println
, micros
하고 delay
.
NOTE2 : 이것은 Arduino IDE와 그것이 제공하는 기본 컴파일러 플래그를 사용하여 수행되었습니다.
NOTE3 : 분석 (플롯 및 계산)은 R을 사용하여 수행되었습니다.