Consider we are using a flag which takes a 0 or 1 value in a embedded programming. Thus we need only 1 bit. However when CPU access data it would access all the 8 bit associated with it. Is this a waste of CPU? Is there a technique to avoid this inefficiency?
3 Answers
Traditionally, Accessing a single bit requires reading the entire word, masking the single bit of interest then acting on the result.
Modifying a single bit required a read, mask and modify, ORing or ANDing depending setting or clearing then writing the result back. The so called "read-modify-write" action. Yes this is inefficient.
A solution called "bit-banding" sets aside a region of memory whose address map to single bits primarily for peripherals.
I used this for the first time in the ARM Cortex-M3. Arm's solution is accessible in C-programming.
It depends on CPU.
Some can access a single bit and some don't.
In any programming language you can store 8 flags per 8-bit byte yourself or with the help of the language if it supports the feature, e.g. C language bit fields.
If you have a lot of flags this may help so less memory is wasted. For a moder CPU with megabytes or gigabytes of memory it hardly matters, but for a small microcontroller with no RAM at all it may help to use the small amount of registers as storage.
A simple CPU with an 8-bit bus will simply access 8 bits at a time, as part of a single memory operation which isn't divisible further. This is the case for anything from a tiny AVR that reads an 8-bit register even when you just care about one GPIO, to a high-end x86_64 CPU that will load a whole byte in a single mov ... [byte ptr]
instruction, while possibly loading an entire cache line (as large as 64 bytes) into the L1 cache. This isn't an "inefficiency", per se - it's simplicity that allows better performance and better efficiency in the end.
It would require much more hardware and complexity to allow loading a single bit, while the underlying hardware is already offering data in a size that it can work with efficiently. Trying to subdivide the 8-bit bus of the AVR, or the cache lines and memory bus of the x86_64 CPU, would require a profound amount of extra circuitry, control complexity, and resulting silicon area/power consumption/speed penalties. As RussellH's answer points out, some vendors have made the choice to support that functionality with its requisite complexity, but it's not a tradeoff that makes sense for all hardware.