• @SW42@lemmy.world
    link
    fedilink
    221 month ago

    Joke’s on you, I always use 64 bit wide unsigned integers to store a 1 and compare to check for value.

    • @bastion@feddit.nl
      link
      fedilink
      41 month ago

      The alignment of the language and the alignment of the coder must be similar on at least one metric, or the coder suffers a penalty to develop for each degree of difference from the language’s alignment. This is penalty stacks for each phase of the project.

      So, let’s say that the developer is a lawful good Rust zealot Paladin, but she’s developing in Python, a language she’s moderately familiar with. Since Python is neutral/good, she suffers a -1 penalty for the first phase, -2 for the second, -3 for the third, etc. This is because Rust (the Paladin’s native language) is lawful, and Python is neutral (one degree of difference from lawful), so she operates at a slight disadvantage. However, they are both “good”, so there’s no further penalty.

      The same penalty would occur if using C, which is lawful neutral - but the axis of order and chaos matches, and there is one degree of difference on the axis of good and evil.

      However, if that same developer were to code in Javascript (chaotic neutral), it would be at a -3 (-6, -9…) disadvantage, due to 2 and 1 degree of difference in alignment, respectively.

      Malbolge (chaotic evil), however, would be a -4 (-8, -12) plus an inherent -2 for poor toolchain availability.

      …hope this helps. have fun out there!

      • @squaresinger@lemmy.world
        link
        fedilink
        120 days ago

        If JS is chaotic neutral, what then is chaotic evil?

        All I’m saying is

        "10" + 1 => "101"
        "10" - 1 => 9
        "a" - "b" => NaN
        
        • @bastion@feddit.nl
          link
          fedilink
          219 days ago

          fair enough. My personal opinion might be that it’s evil, but perhaps that’s because I expected some kind of order.

  • Ice
    link
    fedilink
    51 month ago

    …or you can be coding assembler - it’s all just bits to me

  • Subverb
    link
    fedilink
    38
    edit-2
    1 month ago

    The 8-bit Intel 8051 family provides a dedicated bit-addressable memory space (addresses 20h-2Fh in internal RAM), giving 128 directly addressable bits. Used them for years. I’d imagine many microcontrollers have bit-width variables.

    bit myFlag = 0;

    Or even return from a function:

    bit isValidInput(unsigned char input) { // Returns true (1) if input is valid, false (0) otherwise return (input >= '0' && input <= '9'); }

    • @the_tab_key@lemmy.world
      link
      fedilink
      131 month ago

      We could go the other way as well: TI’s C2000 microcontroller architecture has no way to access a single byte, let alone a bit. A Boolean is stored in 16-bits on that one.

      • @malank@lemm.ee
        link
        fedilink
        101 month ago

        ARM has bit-banding specifically for this. I think it’s limited to M-profile CPUs (e.g. v7-M) but I’ve definitely used this before. It basically creates a 4-byte virtual address for every bit in a region. So the CPU itself can’t “address” a bit but it can access an address backed by only 1 bit of SRAM or registers (this is also useful to atomically access certain bits in registers without needing to use SW atomics).

      • @Treczoks@lemmy.world
        link
        fedilink
        11 month ago

        Tell this to the LPC1114 I’m working with. Did you ever run a multilingual GUI from 2kbytes RAM on a 256x32 pixel display?

        • Subverb
          link
          fedilink
          11 month ago

          I did a multilingual display with an 8031 in 1995 on a 2x16 text LCD. I had 128 bytes of RAM and an EPROM. Did English, Spanish and German.

          You kids have it so easy nowadays. 🤣

          • @Treczoks@lemmy.world
            link
            fedilink
            11 month ago

            Last counting was 114 languages on the LPC1114. And yes, with normal LCDs I’ve done similar things on an 8051 before.

  • @finitebanjo@lemmy.world
    link
    fedilink
    21 month ago

    Does anybody ever figure in parity when comparing bit sizes and all that jazz or are we only ever concerned with storage space?

  • Lucy :3
    link
    fedilink
    861 month ago

    Then you need to ask yourself: Performance or memory efficiency? Is it worth the extra cycles and instructions to put 8 bools in one byte and & 0x bitmask the relevant one?

    • Nat (she/they)
      link
      fedilink
      241 month ago

      A lot of times using less memory is actually better for performance because the main bottleneck is memory bandwidth or latency.

      • Cethin
        link
        fedilink
        English
        81 month ago

        Yep, and anding with a bit ask is incredibly fast to process, so it’s not a big issue for performance.

      • @timhh@programming.dev
        link
        fedilink
        21 month ago

        It’s not just less memory though - it might also introduce spurious data dependencies, e.g. to store a bit you now need to also read the old value of the byte that it’s in.

        • @anton@lemmy.blahaj.zone
          link
          fedilink
          31 month ago

          It might also introduce spurious data dependencies

          Those need to be in the in smallest cache or a register anyway. If they are in registers, a modern, instruction reordering CPU will deal with that fine.

          to store a bit you now need to also read the old value of the byte that it’s in.

          Many architectures read the cache line on write-miss.

          The only cases I can see, where byte sized bools seems better, are either using so few that all fit in one chache line anyways (in which case the performance will be great either way) or if you are repeatedly accessing a bitvector from multiple threads, in which case you should make sure that’s actually what you want to be doing.

        • Nat (she/they)
          link
          fedilink
          11 month ago

          Could definitely be worse for latency in particular cases, but if we imagine a write heavy workload it still might win. Writing a byte/word basically has to do the same thing: read, modify write of cache lines, it just doesn’t confuse the dependency tracking quite as much. So rather than stalling on a read, I think that would end up stalling on store buffers. Writing to bits usually means less memory, and thus less memory to read in that read-modify-write part, so it might still be faster.

    • @mmddmm@lemm.ee
      link
      fedilink
      1601 month ago

      And compiler. And hardware architecture. And optimization flags.

      As usual, it’s some developer that knows little enough to think the walls they see around enclose the entire world.

      • Lucien [he/him]
        link
        fedilink
        141 month ago

        Fucking lol at the downvoters haha that second sentence must have rubbed them the wrong way for being too accurate.

      • @timhh@programming.dev
        link
        fedilink
        41 month ago

        I don’t think so. Apart from dynamically typed languages which need to store the type with the value, it’s always 1 byte, and that doesn’t depend on architecture (excluding ancient or exotic architectures) or optimisation flags.

        Which language/architecture/flags would not store a bool in 1 byte?

        • @mmddmm@lemm.ee
          link
          fedilink
          11 month ago

          Apart from dynamically typed languages which need to store the type with the value

          You know that depending on what your code does, the same C that people are talking upthread doesn’t even need to allocate memory to store a variable, right?

            • @timhh@programming.dev
              link
              fedilink
              21 month ago

              I think he’s talking about if a variable only exists in registers. In which case it is the size of a register. But that’s true of everything that gets put in registers. You wouldn’t say uint16_t is word-sized because at some point it gets put into a word-sized register. That’s dumb.

        • @brian@programming.dev
          link
          fedilink
          21 month ago

          things that store it as word size for alignment purposes (most common afaik), things that pack multiple books into one byte (normally only things like bool sequences/structs), etc

          • @timhh@programming.dev
            link
            fedilink
            11 month ago

            things that store it as word size for alignment purposes

            Nope. bools only need to be naturally aligned, so 1 byte.

            If you do

            struct SomeBools {
              bool a;
              bool b;
              bool c;
              bool d;
            };
            

            its 4 bytes.

            • @brian@programming.dev
              link
              fedilink
              21 month ago

              sure, but if you have a single bool in a stack frame it’s probably going to be more than a byte. on the heap definitely more than a byte

              • @timhh@programming.dev
                link
                fedilink
                11 month ago

                but if you have a single bool in a stack frame it’s probably going to be more than a byte.

                Nope. - if you can’t read RISC-V assembly, look at these lines

                        sb      a5,-17(s0)
                ...
                        sb      a5,-18(s0)
                ...
                        sb      a5,-19(s0)
                ...
                

                That is it storing the bools in single bytes. Also I only used RISC-V because I’m way more familiar with it than x86, but it will do the same thing.

                on the heap definitely more than a byte

                Nope, you can happily malloc(1) and store a bool in it, or malloc(4) and store 4 bools in it. A bool is 1 byte. Consider this a TIL moment.

                • @brian@programming.dev
                  link
                  fedilink
                  11 month ago

                  c++ guarantees that calls to malloc are aligned https://en.cppreference.com/w/cpp/memory/c/malloc .

                  you can call malloc(1) ofc, but calling malloc_usable_size(malloc(1)) is giving me 24, so it at least allocated 24 bytes for my 1, plus any tracking overhead

                  yeah, as I said, in a stack frame. not surprised a compiler packed them into single bytes in the same frame (but I wouldn’t be that surprised the other way either), but the system v abi guarantees at least 4 byte alignment of a stack frame on entering a fn, so if you stored a single bool it’ll get 3+ extra bytes added on the next fn call.

                  computers align things. you normally don’t have to think about it. Consider this a TIL moment.

  • @KindaABigDyl@programming.dev
    link
    fedilink
    1821 month ago
    typedef struct {
        bool a: 1;
        bool b: 1;
        bool c: 1;
        bool d: 1;
        bool e: 1;
        bool f: 1;
        bool g: 1;
        bool h: 1;
    } __attribute__((__packed__)) not_if_you_have_enough_booleans_t;
    
    • @h4x0r@lemmy.dbzer0.com
      link
      fedilink
      English
      161 month ago

      This was gonna be my response to OP so I’ll offer an alternative approach instead:

      typedef enum flags_e : unsigned char {
        F_1 = (1 << 0),
        F_2 = (1 << 1),
        F_3 = (1 << 2),
        F_4 = (1 << 3),
        F_5 = (1 << 4),
        F_6 = (1 << 5),
        F_7 = (1 << 6),
        F_8 = (1 << 7),
      } Flags;
      
      int main(void) {
        Flags f = F_1 | F_3 | F_5;
        if (f & F_1 && f & F_3) {
          // do F_1 and F_3 stuff
        }
      }
      
      • @anotherandrew@lemmy.mixdown.ca
        link
        fedilink
        English
        1
        edit-2
        1 month ago

        Why not if (f & (F_1 | F_3)) {? I use this all the time in embedded code.

        edit: never mind; you’re checking for both flags. I’d probably use (f & (F_1 | F_3)) == (F_1 | F_3) but that’s not much different than what you wrote.

    • @xthexder@l.sw0.com
      link
      fedilink
      40
      edit-2
      1 month ago

      Or just std::bitset<8> for C++. Bit fields are neat though, it can store weird stuff like a 3 bit integer, packed next to booleans

      • Sonotsugipaa
        link
        fedilink
        English
        10
        edit-2
        1 month ago

        That’s only for C++, as far as I can tell that struct is valid C

  • @kiri@ani.social
    link
    fedilink
    21
    edit-2
    1 month ago

    I have a solution with a bit fields. Now your bool is 1 byte :

    struct Flags {
        bool flag0 : 1;
        bool flag1 : 1;
        bool flag2 : 1;
        bool flag3 : 1;
        bool flag4 : 1;
        bool flag5 : 1;
        bool flag6 : 1;
        bool flag7 : 1;
    };
    

    Or for example:

    struct Flags {
        bool flag0 : 1;
        bool flag1 : 1:
        int x_cord : 3;
        int y_cord : 3;
    };
    
    • @lapping6596@lemmy.world
      link
      fedilink
      31 month ago

      I watched a YouTube video where a dev was optimizing unity code to match the size of data that is sent to the cpu using structs just like this.

  • pelya
    link
    fedilink
    301 month ago

    std::vector<bool> fits eight booleans into one byte.

    • @borokov@lemmy.world
      link
      fedilink
      21 month ago
      auto v = std::vector<bool>(8);
      bool* vPtr = v.data;
      vPtr[2] = true;
      // KABOOM !!!
      

      I’ve spent days tracking this bug… That’s how I learned about bool specialisation of std::vector.

    • TimeSquirrel
      link
      fedilink
      61 month ago

      std::vector<std::vector<bool>> is how I stored the representation of a play field for a Tetris game I made once.