[PATCH] Optimize SSE 4.1 x86_64 memcmp

Florian Weimer fweimer@redhat.com
Fri Jan 31 15:10:00 GMT 2014


This patch vectorizes the difference extraction in memcmp.  It does so 
by loading all relevant input bytes, converting them to big-endian using 
BSWAP, and comparing the result.

This changes the return value of memcmp, but stays within the interface 
contract.  Some corner cases in the old implementation do not return 
actual byte differences, either, so I hope this will not break applications.

On my i7-2620M, some lengths (mostly 5, 6, 7) are about one cycle slower 
than the old implementation, but only if all branches in the old 
implementation are correctly predicted.  If there is misprediction (as 
there is bound to be when sorting strings), the vectorized version is 
consistently faster.  The glibc benchtests favor the old 
implementation[*], but the speed difference between tests slightly 
favors the new implementation (but the difference is not clearly 
significant).  I could probably game that by using a data-dependent 
branch in for those lengths, but I think the fully vectorized version is 
better for real-world input data.

In case BSWAP turns out to be too slow for some CPUs, it could be 
replaced with BSF and a shift (both constant time in current 
processors), like we already do in some of the existing memcmp 
implementations.

This work was prompted by a desire to make the time taken by memcmp 
independent of the length of the shared prefix of the arguments as far 
as possible.  The current implementation can still be used to confirm a 
correct guess of a 4-byte or 8-byte prefix, but this is extremely 
unlikely and not suitable for use in a timing oracle (at least the 
8-byte guess).  The new implementation should not act as a cache oracle 
either because it does not perform data-dependent single-byte loads.

If such a change is acceptable in principle, I will make work on similar 
adjustments to the other x86 implementations.

[*] Tight loop over identical inputs, after bumping the inner loop count 
from 64 to 4096.  If I don't do this, the tests are very fragile, but 
the new implementation seems to be roughly twice as fast across the 
board.  Using qsort to sort random strings of fixed length is about 10% 
faster over all using the new implementation.  I still need to try to 
sort a random permutation of /usr/dict/word and compare the results.

-- 
Florian Weimer / Red Hat Product Security Team
-------------- next part --------------
A non-text attachment was scrubbed...
Name: memcmp-sse41.patch
Type: text/x-patch
Size: 3591 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/libc-alpha/attachments/20140131/1cd75f71/attachment.bin>


More information about the Libc-alpha mailing list