Is the choice of 16 as the "limit" value based on benchmarking? As opposed to just doing something like "!buffer[0] && !memcmp(buffer, buffer + 1, size - 1)" which uses the same principle.
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.