4 ms·
Yeah, and as one of the comments to that blog post says, for bit twiddling operations like this, modern compilers are good enough to generate the optimal assemb
by pja 11y ago
Yeah, and as one of the comments to that blog post says, for bit twiddling operations like this, modern compilers are good enough to generate the optimal assembler the vast majority of the time: If you write the equivalent C code
uint32 fill16 = (fill << 8) | fill;
uint32 fill32 = (fill16 << 16) | fill16;
(copied from the comment, so hopefully correct!) you get the benefit of a) not having to fiddle with abstruse register allocation semantics but b) you’re letting gcc use its register allocator to set things up optimally based on the surrounding optimised code.
My own experience with writing memset / memcpy equivalents 10 years ago on x86 was that gcc did a better job of it. Don’t try and outsmart the compiler for this kind of common case unless you know the compiler generates inefficient code - compiler writers have generally got there before you.
- pklausler 11y agouint32 fill32 = 0x01010101 * fill;
- pkaye 11y agoDoing firmware development, I do find many of the C compilers generate sub-optimal bit field type manipulation code.
- slededit 11y agoNo compiler (MSVC, gcc, icc) outputs the "bts" instruction for operations like: bitfield[val / 32] = val % 32; which could implicitly perform the modulo. Using the intrinsic provided significant performance improvements, and we got still more when the rest of the inner loop was rewritten purely in assembly.