🇬🇧
Diese Seite ist Teil eines Framesets. (Index.htm)

Optimierungsbeispiel

Zur Zeitmessung im Sub-Mikrosekundenbereich steht kein freier Timer zur Verfügung, sondern nur einer der bereits als PWM-Generator mit hoher Wiederholfrequenz arbeiten muss.

Von C++ zu handgemachtem Assembler spart 17 Takte und 16 Byte
C++-QuelleKompilatVerbesserung 1Verbesserung 2Verbesserung 3
// Zähler mit Schrittweite 150
static volatile unsigned t1h;

ISR(TIMER1_CAPT_vect) {
 t1h+=150;
}
__vector_14:
	push	r1
	push	r0
	 in	r0, 0x3f
	 push	r0
	 eor	r1, r1
	 push	r24
	 push	r25
	  lds	r24, 0x0110
	  lds	r25, 0x0111
	  subi	r24, 0x6A
	  sbci	r25, 0xFF
	  sts	0x0111, r25
	  sts	0x0110, r24
	 pop	r25
	 pop	r24
	 pop	r0
	out	0x3f, r0
	pop	r0
	pop	r1
	reti
Unnötig gerette Register R0 und R1
.global __vector_14
__vector_14:
	push	r0
	 in	r0,SREG
	 push	r24
	 push	r25
	  lds	r24,t1h
	  lds	r25,t1h+1
	  subi	r24,lo8(-150)
	  sbci	r25,hi8(-150)
	  sts	t1h+1,r25
	  sts	t1h,r24
	 pop	r25
	 pop	r24
	out	SREG,r0
	pop	r0
	reti
Nur ein Rechenregister-Byte
.global __vector_14
__vector_14:
	push	r0
	in	r0,SREG
	push	r24
	 lds	r24,t1h
	 subi	r24,lo8(-150)
	 sts	t1h,r24
	 lds	r24,t1h+1
	 sbci	r24,hi8(-150)
	 sts	t1h+1,r24
	pop	r24
	out	SREG,r0
	pop	r0
	reti
register unsigned isrsave asm("r2");
Gar kein (teures) push mehr
.global __vector_14
__vector_14:
	in	r3,SREG
	mov	r2,r24
	lds	r24,t1h
	subi	r24,lo8(-150)
	sts	t1h,r24
	lds	r24,t1h+1
	sbci	r24,hi8(-150)
	sts	t1h+1,r24
	mov	r24,r2
	out	SREG,r3
	reti

Die optimierte Form braucht …
bei ≤ 8 KByte Flashbei ≥ 16 KByte Flash
  • 4 Takte zum ISR-Aufruf
  • 2 Takte für rjmp in der Interrupttabelle
  • 14 Takte für den Kode (ohne RETI)
  • 4 Takte für RETI
macht zusammen 24 Takte
  • 5 Takte zum ISR-Aufruf
  • 3 Takte für jmp in der Interrupttabelle
  • 14 Takte für den Kode (ohne RETI)
  • 4 Takte für RETI
macht zusammen 26 Takte

Da die ISR alle 150 Takte aufgerufen wird ist die CPU-Last auf einem ATmega16U2 vorher 29 % und nachher 17 %. Auf einem ATmega32U4 wiederum wäre gar keine ISR vonnöten, dieser hat einen Timer mehr.