ein Bit aus DWORD bzw long int auslensen



  • junix schrieb:

    Stimmt, ich taufe meine Markos auch immer "mIsBitSet", "mSetBit" und "mClrBit" und nicht GET_BIT (o;

    au weia, gross/klein gemischt. das sieht ja dann wie 'ne funktion aus 😮

    junix schrieb:

    Denn wenn du schon so päpstlich sein willst, dann ist 1 nicht boolsch sondern integer und das Selbe gilt für 0. In C wiederum gibts nämlich auch keine definitionen dafür.

    1 und 0 ist beides, bool wie auch int 😉
    ...und C99 kennt ja auch schon 'bool'

    junix schrieb:

    Aber wenn dus ganz päpstlich willst, dann wäre ein solches Makro Konsequent:

    #define GET_BIT(value,bit) (((value)&(1<<(bit))) > 0 ? TRUE : FALSE)
    

    Ob das allerdings dem Compiler bei der optimierung hilft...? Der Trick am boolschen ist ja eigentlich der das im Assembler auf "not null" oder eben "null" geprüft wird. (zumindest gilt das für meine IAR Compiler)

    ach nee, besser nicht. dann machste dich davon abhängig wie TRUE und FALSE definiert sind und wenn man pech hat, muss der compiler einen branch mit einbauen. nicht ganz unwichtig an so'nem makro ist ja auch, dass es mit wenigen instructions zeitlich linear abgefrühstückt wird. ein sprung da drin könnte in zeitkritischen codes (wenn's etwa um bruchteile von mikrosekunden geht) schon übel sein, von funktionsaufrufen ganz zu schweigen (aber das haben wir ja schon hinter uns gelassen) 🙂
    :xmas2:



  • ten schrieb:

    junix schrieb:

    Stimmt, ich taufe meine Markos auch immer "mIsBitSet", "mSetBit" und "mClrBit" und nicht GET_BIT (o;

    au weia, gross/klein gemischt. das sieht ja dann wie 'ne funktion aus 😮

    deshalb die Markierung mit "m". Eine Funktion würde "IsBitSet" heissen.

    junix schrieb:

    Aber wenn dus ganz päpstlich willst, dann wäre ein solches Makro Konsequent:

    #define GET_BIT(value,bit) (((value)&(1<<(bit))) > 0 ? TRUE : FALSE)
    

    Ob das allerdings dem Compiler bei der optimierung hilft...? Der Trick am boolschen ist ja eigentlich der das im Assembler auf "not null" oder eben "null" geprüft wird. (zumindest gilt das für meine IAR Compiler)

    ach nee, besser nicht. dann machste dich davon abhängig wie TRUE und FALSE definiert sind und wenn man pech hat, muss der compiler einen branch mit einbauen.

    ten schrieb:

    nicht ganz unwichtig an so'nem makro ist ja auch, dass es mit wenigen instructions zeitlich linear abgefrühstückt wird. ein sprung da drin könnte in zeitkritischen codes (wenn's etwa um bruchteile von mikrosekunden geht) schon übel sein,

    Stimmt... Aber widerspricht das nicht etwas deiner Haltung lieber noch zwei Negierungen einzufügen? Ich würde mal behaupten der Compiler schmeisst die sowieso schon raus. Habs mal mit nem Compiler (mangels was anderem) für Atmel AVR getestet. Keine Optimierungen eingeschaltet. Hab den C-Code mal als Kommentar in die Ausgabe einfügen lassen. Hier mein Vorschlag (hald ohne Makro, macht ja aber keinen Unterschied)

    • SBRC ist Skip if Register Bit is Zero ( Direkter Bitbefehl )
    //    5     unsigned volatile char test=0x80;
            LDI	R16, 128
            ST	Y, R16
    //    6 
    //    7     if (test & (1 << 4))
            LD	R16, Y
            SBRC	R16, 4
    //    8     {
    //    9         __no_operation();
            NOP
    //   10     }
    

    Deine Variante:

    //    5     unsigned volatile char test=0x80;
            LDI	R16, 128
            ST	Y, R16
    //    6 
    //    7     if (!!(test & (1 << 4)))
            LD	R16, Y
            SBRC	R16, 4
    //    8     {
    //    9         __no_operation();
            NOP
    //   10     }
    

    Wie man sieht wird deine doppelte Negierung direkt übersprungen.

    Der Trick soll ja grade sein, dass keine unnötigen Rechenoperationen stattfinden und man deshlab direkt auf die BIts testet.

    Leider krieg ich mein dev-cpp nicht dazu Assembler auszuspucken...



  • ten schrieb:

    junix schrieb:

    Makros ... machen oft auch das Debuggen nicht leichter.

    inline funktionen ebenso wenig. ich mache öfters mal mit codewarrior-compilern rum. die erzeugen an sich schon ziemlich aggressiv optimierten code

    Beim Debuggen schaltet man Optimierungen i.d.R. aus 😉



  • junix schrieb:

    Aber widerspricht das nicht etwas deiner Haltung lieber noch zwei Negierungen einzufügen? Ich würde mal behaupten der Compiler schmeisst die sowieso schon raus.

    ja, die zwei negierungen sorgen dafür, dass es 'logisch richtig' ist, fliegen aber im erzeugten maschinencode komplett raus, wenn man den output von GET_BIT auf wahr oder falsch überprüft (if, while, ect.). wenn man GET_BIT() einer variablen zuweist, z.b. "int x = GET_BIT(...);", dann sorgt der compiler dafür, dass nix anderes als 0 oder 1 in dieser variablen landet. natürlich erkennt er auch hierbei die beiden negierungen direkt hintereinander und kann das sehr gut optimieren...


Anmelden zum Antworten