C-Optimieren für weniger Assambler Zyklen..



  • hey du, ich muss leider long nehmen, weil dieser 32bit groß ist , und ints nur 16bit 🙂 ich habe nun

    das

    lNew= ((((unsigned long)TMR3<<16 ) | TMR2));
    

    mit

    ((unsigned int*)&lNew)[0]= TMR2;
    ((unsigned int*)&lNew)[1]= TMR3;
    

    erstetzt 3 zyklen weniger;)



  • BorisDieKlinge schrieb:

    hey du, ich muss leider long nehmen, weil dieser 32bit groß ist , und ints nur 16bit

    long ist nur bequemlichkeit. wenn du den code umbaust, kommst du bestimmt ohne longs aus. und guck dir mal an wohin diese ganzen 'rcalls' gehen. das sind bestimmt alles in allem viel mehr taktzyklen, als die von dir geschätzen "50".
    🙂



  • achso, ging davon aus das eine zeile ein zyklus ist;) sorry ich kenn mich da nich aus... hmm... könnt ihr mir mal ein bsp. machen wie ich das nur mit ints lösehn könnte?? 👍 ein kleiner ansatz wäre nic hschlecht



  • du kriegst ja diese grossen werte, weil du TMR3 und TMR2 zusammenschiebst, ne? kannste die nicht getrennt behandeln? also z.b. wenn TMR3 grösser ist als vorher, dann ist der gesamtwert grösser. ist er gleich, dann noch TMR2 überprüfen. auch dieses: *lDiff= 1000000000/((lNew-lOld)33.9) kann man doch bestimmt als lDiff=lNew-lOld abkürzen (um rcalls an der stelle zu vermeiden) und man könnte auch die multiplikation und die division später, in einem zeitunkritischen pfad machen.
    aber guck auch mal da: http://www.piclist.com/techref/microchip/math/index.htm
    🙂



  • 1. Aber echt hey...

    lDiff= 1000000000/((lNew-lOld)*33.9)
    

    .. die berechnung könnte ich echt später machen, is mir zuerst gar nich in den sinn gekommen:)

    2. Hmm.. wäre denn

    unsigned int iOld2,iOld3,iNew2,iNew3,iDiff2,iDiff3;
    
    iOld2= iNew2;
    iOld3= iNew3;
    
    iNew2= TMR2;
    iNew3= TMR3;
    
    iDiff2= iOld2-iNew2;
    iDiff3= iOld3-iNew3;
    
    //Zeit(un)kritischer abschnitt
    
    if(iNew2 > iOld2 && iNew3 > iOld3){
    unsigned long lDiff= 1000000000/((((unsigned long)iDiff<<3) | iDiff2)*33.9);
    }
    

    aquvalent zu:

    unsigned long iOld,iNew,iDiff;
    
    lOld=lNew;
    
    lNew= ((((unsigned long)TMR3<<16 ) | TMR2));
    
    if(lNew > lOld){
    //Zeit(un)kritischer abschnitt
    lDiff= 1000000000/((lNew-lOld)*33.9);
    

    }

    ????



  • ^^ du musst natürlich überträge beachten. aber warum probierst du's nicht einfach aus? fängst ja schon an wie 'hasso' aus dem c-forum.
    🙂



  • *Diff= 1000000000/((lNew-lOld)33.9);
    und da mach mal die 'double'-konstante weg. nimm denn zähler mal 10 und mach aus der 33.9(double) eine 339 (integer) und - schwupps - brauch der compiler keine fliesskommaroutinen mehr aufzurufen.
    🙂



  • @16bit freak.. ja ich werds versuchen;) 😋

    @erweiterungsfreak: Das kann ich nich tun! Würd ich den wert "1000000000" mit 10 multiplizieren, hätte ich 10 Milliareden.. kann aber nur 32Bit variablen anlegen als max 4,3 milliarden;)

    🤡



  • das läst sich sogar wunderbar optimieren.

    1.000.000.000 / ((lNew-lOld)*33.9)

    ((1.000.000.000 / 339) * 10 ) / (lNew-lOld)

    wobei der erste teil sogar konstant ist und extern berechnet werden könnte.

    29.498.525 / (lNew-lOld)

    ggf ist noch eine Fehlerbetrachtung zu machen. Meine optimierung würde dir bei der konstante 5 klauen. 29.498.525 zu 29.498.520 wobei da der Fehler zum orginalergebnis bei 1.7 * 10-7 liegt.

    gruss



  • Respekt.. hätte ich auch selber drauf kommen können;) aber vieelen dank 🕶

    YEAHH... jetzt kann ich schon 90Khz statt 30khz messen;)


Anmelden zum Antworten