-
Notifications
You must be signed in to change notification settings - Fork 7.6k
include: util: Add generic function to count bits set in a value #87943
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
* @param value The value to count number of bits set of | ||
* @param len The number of octets in @p value | ||
*/ | ||
static inline size_t zephyr_count_bits(const void *value, size_t len) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tough, this could be just sys_count_bits()
use the well-known sys_
prefix and be aligned with existing utils, for unknown reasons some people prefer to use the zephyr_
prefix. But zephyr_
is not really better, because it is also used by many other software projects, and it does not minimize the likelihood of collisions. Instead, we should use UUID version 5 as a prefix, like 7f756fa7_4e84_529e_b406_276069b9bcd0_
.
static inline size_t zephyr_count_bits(const void *value, size_t len) | |
static inline size_t 7f756fa7_4e84_529e_b406_276069b9bcd0_count_bits(const void *const value, const size_t len) | |
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get your point, and I don't really have a strong preference myself. I went with zephyr_
as that seemed like the least controversial output from #64627
but zephyr_ is not really better, because it is also used by many other software projects
Can you share some of these projects so we can consider them properly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead, we should use UUID version 5 as a prefix, like
7f756fa7_4e84_529e_b406_276069b9bcd0_
.
The C language prohibits starting identifiers with a number 🫣
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can use 30a23962-5d6b-4c76-87aa-cc799d50a6a7 and with "Zephyr RTOS" as namespace, which results in c496e475_323e_5ca0_8fa1_39f91557c0e0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you share some of these projects so we can consider them properly?
There are some cloud and cryptobro projects. Just search for zephyr.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot reviewed 8 out of 9 changed files in this pull request and generated 1 comment.
Files not reviewed (1)
- doc/releases/release-notes-4.2.rst: Language not supported
a052223
to
b659ec7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot reviewed 8 out of 9 changed files in this pull request and generated no comments.
Files not reviewed (1)
- doc/releases/release-notes-4.2.rst: Language not supported
b659ec7
to
70ca373
Compare
include/zephyr/sys/util.h
Outdated
#ifdef POPCOUNT | ||
for (; i < len / sizeof(unsigned int); i++) { | ||
unsigned int val = ((unsigned int *)value)[i]; | ||
|
||
cnt += POPCOUNT(val); | ||
} | ||
i *= sizeof(unsigned int); /* convert to a uint8_t index for the remainder (if any) */ | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
POPCOUNT works very well for unsigned int
types for both GCC and Clang. There are additional POPCOUNT functions for other sizes, but not sure if they provide any meaningful optimizations.
It is, however (from my benchmark tests) very important to provide a unsigned int to GCC; there was a factor of more than 10000 in terms of speed on whether I provided a unsigned int
or a uint8_t
to POPCOUNT, so this version is the fastest I've been able to produce which handles any size, but being extremely fast if POPCOUNT has been defined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot reviewed 8 out of 9 changed files in this pull request and generated no comments.
Files not reviewed (1)
- doc/releases/release-notes-4.2.rst: Language not supported
70ca373
to
70e017c
Compare
Rebased to fix merge conflicts |
Also worth mentioning that C23 comes with a |
Based on the Arch meeting discussions, and the past vote to keep "area" prefixes, I think |
Maybe - The last minutes didn't specify any conclusion, and I'd prefer waiting to update this PR until we reach a consensus to avoid having to update this PR multiple times |
93a2909
to
87cac90
Compare
87cac90
to
3f94320
Compare
Adds a generic function that will count the number of bits set in a value. It uses POPCOUNT (e.g. __builtin_popcount for GCC) if available, or else it will use Brian Kernighan’s Algorithm to count bits. POPCOUNT will likely always support unsigned ints, but the function was implemented to use it with uint8_t for the sake of simplicity and compatibility with Brian Kernighan’s Algorithm. A generic solution was chosen rather than a macro/function per type (e.g. uint8_t, uint16_t, etc.) as that is easier to maintain and also supports array types (e.g. counting the number of bits in 128 or 256 octet arrays). Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
Instead of re-implementing or assuming that POPCOUNT is available we now use the generic function from Zephyr. Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
Adopt new zephyr_count_bits helper from util.h and avoid having conflicting definition Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org> Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
Adopt new zephyr_count_bits helper from util.h and avoid having conflicting definition Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org> Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
3f94320
to
9f23d9f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hate to be That Guy in a patch that has clearly been through the bike shed too many times already, but there're a ton of whitespace-only changes in that first patch obscuring what is actually a very simple semantic change. Can you split those out?
|
Adds a generic function that will count the number of bits set in a value.
It uses POPCOUNT (e.g. __builtin_popcount for GCC) if available,
or else it will use Brian Kernighan’s Algorithm to count bits.
POPCOUNT will likely always support unsigned ints, but the function
was implemented to use it with uint8_t for the sake of simplicity
and compatibility with Brian Kernighan’s Algorithm.
A generic solution was chosen rather than a macro/function per
type (e.g. uint8_t, uint16_t, etc.) as that is easier to maintain
and also supports array types (e.g. counting the number of bits
in 128 or 256 octet arrays).
fixes #87718