Union für mehr performance ?



  • Hallo Leute !

    Ich habe folgende Idee und würde gerne mal wissen ob
    das möglich und ok ist oder eher ein hack den man
    nicht machen sollte.

    Ich habe 4 bool variablen und möchte :
    1. jede einzelne auf true/false testen können
    2. mit nur einem "Zugriff" testen können ob alle false sind

    Um das zu ermöglichen dachte ich mir verwende ich unio wie folgt :

    struct BoolBundle
    {
      bool A;
      bool B;
      bool C;
      bool D;
    };
    
    union {
      unsigned int ZeroIfAllFalse;
      BoolBundle   Boolean;
    };
    

    4x 1Byte große bool Variablen teilen sich also den gleichen Speicher mit
    1x 4Byte großer unsigned int Variable. Sind alle A,B,C,D false, dann ist
    auch ZeroIfAllFalse==0, richtig ?

    Somit könnte ich ganz einfach mit
    if (ZeroIfAllFalse==0) prüfen ob alle false sind.

    Ich müßte blos prüfen ob unsigned int immer genauso groß ist
    wie 4 bytes (was auf 32bit systemen ja der Fall ist). 😃

    Was haltet Ihr davon, ist es unsinnig sowas zu machen weil
    es eher ein hack ist und vielleicht es doch irgendwie probleme
    geben könnte oder könnte ich das einfach so machen wenn ich
    vor dem Programmstart noch teste ob
    sizeof(unsigned int) == 4*sizeof(byte) ist ? 🙂

    Freu mich über Eure Meinungen, es müßte doch auf jedenfall schneller
    sein als wenn ich statt (ZeroIfAllFalse==0) prüfen müßte ob
    !(A || B || C || D) oder ?



  • ich würd's vielleicht eher so machen:

    bool bool_bundle[4];
    unsigned int *all_bools = (unsigned int*)bool_bundle;
    ...
      if (*all_bools == 0)
      {
          // alle sind false
      }
    ...
    


  • ja auch eine Möglichkeit, aber ist die nicht etwas
    langsamer weil da noch derefernziert wird ? 😕



  • dereferenziert



  • dann vielleicht so

    ...
    #define ALL_BOOLS *(unsigned int*)bool_bundle
    ...
    if (ALL_BOOLS == 0)
    {
       // alle bools false
    }
    ...
    

    dabei wird zwar auch dereferenziert aber es ist kein umweg über 'ne pointervariable d.h. kann besser optimiert werden.

    zu der struct/union konstruktion hätt' ich weniger vertrauen wegen alignment und sowas....



  • Stimmt ich glaub ich mach das lieber so wie Du schreibst,
    das mit dem Alignment ist wirklich noch ne kleine Gefahr.

    Danke !! 🙂



  • Achso, aber wenn ich einzeln auf die bools zugreifen will,
    ist dann z.B. das

    if (bool_bundle[2])
    {
      // do something beautiful
    }
    

    auch wirklich nicht langsamer als ein
    struct Zugriff auf das union wie

    if (Boolean.B)
    {
      // do something beautiful
    }
    

    ? Weiß leider nicht was der Compiler da anstellt ?



  • Schnulla schrieb:

    Achso, aber wenn ich einzeln auf die bools zugreifen will,
    ist dann z.B. das

    if (bool_bundle[2])
    {
      // do something beautiful
    }
    

    auch wirklich nicht langsamer als ein
    struct Zugriff auf das union wie

    if (Boolean.B)
    {
      // do something beautiful
    }
    

    ? Weiß leider nicht was der Compiler da anstellt ?

    ich denke darum musste dir keine sorgen machen.
    wenn der index ein fester wert ist, wird im ausführbaren code sehr wahrscheinlich keine berechnung 'array+index' o.ä. mehr vorkommen.
    ausser du schaltest alle optimierungen aus, aber selbst dann wohl nicht.
    probier's doch einfach mal aus und schau dir das disassembly an...



  • if (!bool_bundle[3])
    005175CE movzx eax,byte ptr [ebp-11h]
    005175D2 test eax,eax
    005175D4 jne 00517611
    {

    macht er draus



  • Also schön flotter Zugriff genauso wie auf eine einzeln
    deklarierte bool variable 🙂 Cool dann mach ich das so,
    also danke nochmal ! 👍
    cu


Anmelden zum Antworten