-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 17

Thema: Fehler beim Multiplizieren? Weiß nicht mehr weiter!

  1. #1
    Erfahrener Benutzer Begeisterter Techniker Avatar von Jacob2
    Registriert seit
    26.05.2007
    Ort
    Berlin
    Beiträge
    345

    Fehler beim Multiplizieren? Weiß nicht mehr weiter!

    Anzeige

    Hallo,
    Ich (eigentlich eher mein Programm) habe ein Problem und zwar folgendes:
    Bei mir bewirken folgende Zeilen nicht dasselbe:
    Code:
    int ba = 6, tempo = 45, temp;
    temp = 8505 - (ba * tempo);
    for (i=0; i < temp; i++) {};
    Code:
    for (i=0; i < 8235; i++) {};
    Wie kann das sein? Wenn ich rechne, müsste jedesmal gleichlang gewartet werden!
    Roboter, CNC Fräse, Elektronik und Basteleien stelle ich auf meiner Website vor...

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von vohopri
    Registriert seit
    11.09.2004
    Ort
    südlich der Alpen
    Beiträge
    1.708
    Hallo,

    1. was genau steht in {} bei der Ausführung?

    2. wie schaut das Compilat dieser Schleife (der Assemblercode vom Debugger) in beiden Fällen aus? Ganz das gleiche wird nicht gemacht. einmal wird eine Variable ausgewertet und einmal eine Konstante, die anders abgespeichert sein kann.

    3. Welchen Typ hat temp?

    grüsse,
    vohopri

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791
    Hallo Jacob2,

    es sind ja auch nicht identische Schleifen.
    Die Endebedingung (i < ...) testet beim ersten Mal 2 Variablen (i, temp) gegeneinander, beim zweiten Mal eine Variable (i) gegen eine Konstante (8235).

    Die Schleifen sind also nicht identisch.

    Wenn sie dann auch noch zum WARTEN benutzt werden, dann produzieren sie eben verschiedene Ablaufzeiten.

    Gruß Dirk

  4. #4
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.781
    Blog-Einträge
    8
    Wie ist diese Variante?

    temp=8235;
    for (i=0; i < temp; i++) {};

    War mal wieder zu langsam :)

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  5. #5
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791
    War mal wieder zu langsam
    Obwohl: Der Hai erwischt dich ja (bis jetzt) nie ...

    Gruß Dirk

  6. #6
    Erfahrener Benutzer Begeisterter Techniker Avatar von Jacob2
    Registriert seit
    26.05.2007
    Ort
    Berlin
    Beiträge
    345
    @vohopri
    1. Da steht nichts, es soll nur gewartet werden.
    2. Ich weiß nicht wo man das sehen kann.
    3. temp ist ein Integer

    @Dirk Die Variable hat aber den selben Wert wie die Konstante! Identisch sind sie natürlich nicht, aber sie müssten doch gleich lange dauern oder?

    @radbruch Es passiert das selbe, es muss daran liegen, dass es einmal eine Zahl und einmal eine Variable ist!

    Hat vielleicht noch jemand eine Idee, es soll nämlich ein Weihnachtsgeschenk werden
    Roboter, CNC Fräse, Elektronik und Basteleien stelle ich auf meiner Website vor...

  7. #7
    Erfahrener Benutzer Robotik Einstein Avatar von vohopri
    Registriert seit
    11.09.2004
    Ort
    südlich der Alpen
    Beiträge
    1.708
    Das ist es ja: der selbe wert wird von unterschiedlichen Speichern geholt - abhängig davon, obs eine Variable oder eine Kostante ist. Und das braucht unterschiedlich viel Zeit. Wenn zwei verschieden lang dauernde Vorgänge gleich oft durchführst, dann dauerts unterschiedlich lang.

    Mit einem Debugger, der den Assemblercode anzeigt, wäre das gut sichtbar.

    grüsse,
    v.

  8. #8
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Ohne optimierung wird ein anderer vergleich durchgeführt. Da kannes schon mal zu etwas anderen Laufzeiten kommen. Mit optimierung könnte in beiden Fällen nichts passieren, denn die Schleife könnte komplett wegoptimiert werden, wenn die variable i danach nicht gelesen wird. Eher unwahrscheinlich ist der Fall, dass die optimierung davon abhängt ob da eine Variable oder Konstante steht.

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    12.11.2004
    Ort
    Hvalstad, Norwegen
    Beiträge
    140
    Ich denke eher bei der Konstanten schlägt die Optimierung des Kompilers zu, der lässt nämlich ein Warten auf Konstanten nicht unbedingt zu.
    Radbruchs Variante sollte dein Problem lösen.
    Evtl. noch ein Semikolon in die FOR-Schleife.
    Gruß
    Lorcan

  10. #10
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.781
    Blog-Einträge
    8
    Keine Ahnung wie der Kompiler das anstellt:
    Code:
    int main(void)
    {
    	int i;
    	int ba = 6, tempo = 45, temp;
    	temp = 8505 - (ba * tempo);
    // Schleife1 Anfang
    	for (i=0; i < temp; i++) {};
    // Schleife 1 Ende
    // Schleife2 Anfang
    	for (i=0; i < 8235; i++) {};
    // Schleife2 Ende
    	while(1);
    	return(0);
    }
    Wird bei mir zu
    Code:
    0000005c <main>:
    int main(void)
    {
      5c:	cf e5       	ldi	r28, 0x5F	; 95
      5e:	d4 e0       	ldi	r29, 0x04	; 4
      60:	de bf       	out	0x3e, r29	; 62
      62:	cd bf       	out	0x3d, r28	; 61
      64:	8a e2       	ldi	r24, 0x2A	; 42
      66:	90 e2       	ldi	r25, 0x20	; 32
    	int i;
    	int ba = 6, tempo = 45, temp;
    	temp = 8505 - (ba * tempo);
    // Schleife1 Anfang
    	for (i=0; i < temp; i++) {};
      68:	8d 97       	sbiw	r24, 0x2d	; 45
      6a:	97 ff       	sbrs	r25, 7
      6c:	fd cf       	rjmp	.-6      	; 0x68 <main+0xc>
      6e:	8a e2       	ldi	r24, 0x2A	; 42
      70:	90 e2       	ldi	r25, 0x20	; 32
    // Schleife 1 Ende
    // Schleife2 Anfang
    	for (i=0; i < 8235; i++) {};
      72:	8d 97       	sbiw	r24, 0x2d	; 45
      74:	97 ff       	sbrs	r25, 7
      76:	fd cf       	rjmp	.-6      	; 0x72 <main+0x16>
    // Schleife2 Ende
    	while(1);
      78:	ff cf       	rjmp	.-2      	; 0x78 <main+0x1c>
    Identischer Code! 68-6c bzw. 72-76, hier mein Output beim Kompilieren:
    Code:
    rm -f test.hex
    rm -f test_eeprom.hex
    rm -f test.elf
    rm -f test.map
    rm -f test.cof
    rm -f test.lst
    rm -f temp.lst
    rm -f temp.o
    avr-gcc -mmcu=atmega8 -Os -mno-interrupts -funsigned-char -funsigned-bitfields -Wall -Wstrict-prototypes -ggdb -c -DF_CPU=8000000UL -Wa,-acdhlmns=temp.lst temp.c -o temp.o
    avr-gcc -mmcu=atmega8 -Os -mno-interrupts -funsigned-char -funsigned-bitfields -Wall -Wstrict-prototypes -ggdb temp.o -o test.elf -Wl,-Map=test.map --cref -lm
    avr-objcopy -j .text -j .data -O ihex test.elf test.hex
    avr-objcopy -j .eeprom --change-section-lma .eeprom=0 -O ihex test.elf test_eeprom.hex
    avr-objdump -d -S test.elf > test.lst
     0
    Verblüffend.

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •