- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 22

Thema: Compiler Multiplikation verbieten

  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076

    Compiler Multiplikation verbieten

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo zusammen,

    in einem kleinen 8 Bitter ist eine Multiplikation ja nicht grad optimal, da sie in Software ausgeführt wird.
    Wenn ich nun einen Wert mit 3 multiplizieren möchte, habe ich ja so einiges an Möglichkeiten.
    Ich habe mal verschiedene Möglichkeiten compiliert und war doch sehr erstaunt über das Ergebnis:
    Um den Compiler auszutricksen habe ich folgenden Code verwendet und genau der ist laufzeitmässig der absolut Schlechteste:

    Compiler ist der XC8 Version V2.00

    char cnt;

    Code:
    cnt  = cnt + cnt + cnt;    // 57 Zyklen
    So wie ich es in Assembler gemacht hätte, hat auch der Compiler die beste Laufzeit.
    Code:
    cnt  = (cnt << 1) + cnt;   //  5 Zyklen
    Hier mal die Übersicht:
    Code:
    cnt *=3;                   // 45 Zyklen
    cnt  = (cnt << 1) + cnt;   //  5 Zyklen
    cnt  = cnt + cnt + cnt;    // 57 Zyklen
    cnt += (cnt + cnt);        // 56 Zyklen
    Ich möchte halt vermeiden, dass der schlaue C-Compiler mir eine Multiplikation erzeugt.
    Kann man das noch irgendwie steuern ?

    Siro

    Wie so oft macht der C-Compiler nicht das was da steht, er konzentriert sich nur auf das Ergebnis. Hier fehlt eigentlich eine Option: Bitte das so kodieren wie es dort steht. Natürlich ironisch gemeint....
    Geändert von Siro (01.11.2018 um 12:10 Uhr)

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Ein paar Sachen fallen mir dazu ein, die die Laufzeit bei einem 8-Bitter beeinflussen könnte.

    Was für ein Typ ist cnt? Unsigned oder signed? Und welche Größe hat es? Char oder Int? Und zu guter letzt, ist cnt lokal oder global?

    Wie so oft macht der C-Compiler nicht das was da steht, er konzentriert sich nur auf das Ergebnis. Hier fehlt eigentlich eine Option: Bitte das so kodieren wie es dort steht. Natürlich ironisch gemeint....
    Alle von dir gezeigten Ausdrücke brauchen eigentlich eine zusätzliche temporäre Variable, da es mathematische Operationen mit 3 Operanden nicht gibt. Der Compiler erledigt das schon richtig, Seine Strategie mag da aber nicht so leicht zu erkennen sein. Lös das mal in mehrere Zeilen so auf, daß rechts nur eine Operation steht. Dann bleibt dem Compiler nichts anderes übrig, genau das zu tun, was du hinschreibst. So als Beispiel


    Code:
       t = cnt + cnt;
       cnt = cnt + t;
    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Hallo Klebwax,
    ertsmal Danke für deine Info:

    ich habe deinen Code ausprobiert.
    Ich habe beide Variablen als "unsigned char" definiert. GLOBAL
    ohne volatile klaut er den gesamten Code, völlig okay, weil er ihn ja nicht braucht
    Er ruft schon bei der ersten Zeile ein Unterprogramm (Multiplier) auf.

    33 Zyklen
    Code:
    volatile unsigned char t,cnt;
    
    void main(void)
    {
       t = cnt + cnt;   // hier ruft er wieder eine Multiplikation auf. 
       cnt = cnt + t;    
    }
    so macht er aber besseren Code ohne Multiplikation: 15 Zyklen
    Code:
      t = cnt;
      t = t + cnt;
      cnt = t + cnt;
    Ich hoffe, das hängt nicht mit der Lizenz zusammen, da ich ja nur die freie Version vom XC8 benutze...
    Geändert von Siro (01.11.2018 um 19:29 Uhr)

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von Siro Beitrag anzeigen
    Er ruft schon bei der ersten Zeile ein Unterprogramm (Multiplier) auf.

    33 Zyklen
    Code:
    volatile unsigned char t,cnt;
    
    void main(void)
    {
       t = cnt + cnt;   // hier ruft er wieder eine Multiplikation auf. 
       cnt = cnt + t;    
    }
    Ist schon lustig, daß der Compiler in cnt + cnt 2*cnt erkennt. Ich hab anderes ähnliches gefunden: für t = 1 erzeugt er clear t und dann inc t.

    so macht er aber besseren Code ohne Multiplikation: 15 Zyklen
    Code:
      t = cnt;
      t = t + cnt;
      cnt = t + cnt;
    Das wäre das, was ich in Assembler schreiben würde, wobei t dann der Akku wäre.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Die Algorithmen sind teils schon lustig.
    für dein Beispiel t=1 kann er alles direkt in den Registern abarbeiten. Er muss dazu keine Konstante (die 1) aus dem Speicher laden. So ist es bei einigen Prozessoren eventuell schneller.

    Ein echtes "Steuern" für den Code scheint aber nicht direkt möglich zu sein, bzw. nicht sicher nachvollziehbar.
    Am schnellsten geht es in diesem Falle (unsigned multiplikation mit 3) immer noch mit
    cnt = (cnt << 1) + cnt;

    mit signed geht das natürlich dann nicht mehr.

    Siro

  6. #6
    HaWe
    Gast
    moinmoin!
    für cnt=3 geht das ntl mit 1x shiften und 1x addieren, aber für cnt >= 4 brauchst du ja wieder Zähler und/oder eine Fallunterscheidung ob cnt gerade oer ungerade.


    Aber nur interessehalber,
    was macht er per

    for(int i=1; i<cnt;i++) t+=x;

    Geändert von HaWe (02.11.2018 um 07:46 Uhr)

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Guten Morgen,
    hab ich auch mal getestet:

    Code:
    for(i=0; i<3;i++) cnt+=cnt;      // 44 Zyklen, normaler Schleifencode, wenn i ein unsigned char ist
    
    for(int i=0; i<3;i++) cnt+=cnt;  // 76 Zyklen, normaler Schleifencode, weil i ein int ist,
    wobei mir grad auffällt, da kommt ja was anderes raus...

    Siro
    Geändert von Siro (02.11.2018 um 07:19 Uhr)

  8. #8
    HaWe
    Gast
    Hatte mich vertippt
    Ntl
    ... t+=x

    cnt ist bei mir der Multiplikator

    PS
    Welche Compileroptimierungsstufe hast du?
    Offenbar musst den Schleifenzähler wirklich auch global definieren
    Geändert von HaWe (02.11.2018 um 07:47 Uhr)

  9. #9
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Code:
    t=cnt; 
    for(i=0; i<2;i++) cnt+=t;
    hier benötigt er 34 Zyklen.

    The current licence does not permit the selected optimization level, using level -O1
    Geändert von Siro (02.11.2018 um 07:43 Uhr)

  10. #10
    HaWe
    Gast
    Edit
    Stimmt
    Hatte mich vertan

    cnt war bei mir der Multiplikator
    x der Multiplikant
    t das Ergebnis

    Also anstelle
    t=x*cnt
    Alternativ:


    int i, x, cnt;
    t=x;
    for( i=1; i<cnt;i++) t+=x;
    Geändert von HaWe (02.11.2018 um 07:57 Uhr)

Seite 1 von 3 123 LetzteLetzte

Ähnliche Themen

  1. Auch Hybridfahrzeuge betroffen: Großbritannien will Verbrenner ab 2040 verbieten
    Von Roboternetz-News im Forum Neuigkeiten / Technik-News / Nachrichten / Aktuelles
    Antworten: 0
    Letzter Beitrag: 26.07.2017, 10:40
  2. Verkehr: Stadtrat in San Francisco will Lieferroboter verbieten
    Von Roboternetz-News im Forum Neuigkeiten / Technik-News / Nachrichten / Aktuelles
    Antworten: 2
    Letzter Beitrag: 24.05.2017, 10:52
  3. Multiplikation falsch??
    Von fredyxx im Forum Arduino -Plattform
    Antworten: 8
    Letzter Beitrag: 20.05.2016, 10:21
  4. Multiplikation in ass
    Von haus51 im Forum Assembler-Programmierung
    Antworten: 9
    Letzter Beitrag: 20.03.2007, 13:48
  5. Vias unter Bauteilen verbieten (Eagle)
    Von Henrik hessert im Forum Konstruktion/CAD/3D-Druck/Sketchup und Platinenlayout Eagle & Fritzing u.a.
    Antworten: 2
    Letzter Beitrag: 16.12.2006, 18:34

Berechtigungen

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

12V Akku bauen