(Might or might not still be true on more modern aarch64 hardware...)
This would eliminate split loads and provide a decent speedup.
https://lemire.me/blog/2012/05/31/data-alignment-for-speed-m...
Memory alignment is innocuous (others than often compromise code legibility).
Loop unrolling, on the other hand, can slow down the code. Specially in small loops.
See Agner uarch PDF.
We can't easily use a larger size because we mustn't read beyond the end of the buffer if it's shorter than 16 bytes and not a multiple of 2, 4, etc.
https://rusty.ozlabs.org/?p=560
Hope that helps!
(And yes, the CCAN memeqzero routine is the same as yours above in form).
It counts how many bits are set to 1, you’re looking for 0.
You can also cast it into a uint64_t integer and do an equality test. There might be a way to use fused multiply add.
Also are you mmaping the file so you can just read it directly as a single buffer? You should be able to madvise to free pages after they’ve been checked.
PUSHFB can also be used. http://0x80.pl/articles/sse-popcount.html
Essentially you want to vectorize this tho memcmp may already be vectorized and do the cpu detection.
Edit: also… You should be able to load 15 x 256 bits and then test them. Try VPTEST https://www.intel.com/content/www/us/en/develop/documentatio...
I haven't looked at the implementation, but you could test it against yours.
strchr(str, 0) == NULL
memchr(str, 0, len) == NULLHuh. OP is right, there is no good function for this in the standard library.
One of the big things about C is that there is no standard library function for anything remotely nontrivial. So successfully coding in C relies on "tricks", and snippets and lore that have been passed on over the years.
Rust, meanwhile, has a check_for_all_zeroes crate or something.
https://gitlab.com/nbdkit/nbdkit/-/blob/b31859402d1404ba0433...
Example usage for sparsifying while copying disk images: https://gitlab.com/nbdkit/libnbd/-/blob/46fa6ecc7422e830f10d...