x86 Assembly Primer for C Programmers
speakerdeck.com
speakerdeck.com
http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/i386...
http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/i386...
It's counter-intuitive that so many instructions can be dedicated to something so seemingly simple like strlen(), but it does highlight the complexity of modern processors. On that note, I do not know and am reluctant to comment on which implementation of strlen() is fastest, as it seems very difficult to decouple the non-determinism of caches, instruction scheduling, pipelines, etc. by only looking at the source, especially when other code is also involved. But there probably is a benchmark that could give some useful results -- to justify the code above too -- like in the link you posted.
Someone with a better understanding of instruction scheduling, pipelines, and other optimizations can probably give a better answer to this than me.
~vsergeev/frozeneskimo
Maybe you or someone else knows the answer to this though: it seems like they are processing 4 bytes of the string at a time. If they read over (i.e. the NULL byte is in byte position 1 2 or 3), isn't that technically undefined behavior? They are only reading in the memory, but I feel like valgrind or another tool would spit out an error if that happened. It's aligned, so it won't trigger a page fault, but it seems like an unsafe optimization.
Another more trivial example of something like this is in the repnz-based strlen() (slides 7-8), where %ecx is loaded with 0xffff ffff, which technically limits the routine to scan strings up to 4 gigabytes in length. It's a valid assumption that the string is under 4GB (especially on a strictly 32-bit system), but the point is that it's a semantically different routine than the C based one.
~vsergeev/frozeneskimo
Only if they are using C, not implementing it. That is why the C standard has that 'undefined behavior' claus. It makes optimizations like this possible.
The biggest difference for me is the difference in the calling convention. In 32 bit, all arguments generally are placed on the stack for "standard" calls. In 64 bit, different OSes have different conventions:
http://en.wikipedia.org/wiki/X86_calling_conventions#x86-64_... (note that OS X and linux use the "System V" calling conventions)
On Windows, amd64 is much better than x86 in this regard because of the bevy of x86 calling conventions that are still around. Only one amd64 calling convention.
Does anyone have a working link to the content?
Content is available here as well: https://github.com/vsergeev/apfcp