On the hunt for safe optimizations for md5
Well, right now I am testing some other optimizations that use strictly safe code. One of the things I came across:
On my fast machine it helps to do as much arithmetic as possible in one go. For example:
- b += (((d ^ a) & c) ^ a) + (uint)K[7] + buff[7];
- b = (b <<22) | (b>> 10);
- b += c;
This b += c is not smart to use in this situation and actually produces a performance hit. Better would be:
- b += (((d ^ a) & c) ^ a) + (uint)K[7] + buff[7];
- b = ((b <<22) | (b>> 10)) + c;
Altering the whole segment like this in the md5 algorithm adds up to a 10-15% performance increase!
Let's look at the IL:
- ldloc.1
- ldloc.3
- ldloc.0
- xor
- ldloc.2
- and
- ldloc.0
- xor
- ldsfld unsigned int32[] MD5CryptoServiceProviderMonoOrig::K
- ldc.i4.7
- ldelem.u4
- add
- ldarg.0
- ldfld unsigned int32[] MD5CryptoServiceProviderMonoOrig::buff
- ldc.i4.7
- ldelem.u4
- add
- add
- stloc.1
- ldloc.1
- ldc.i4.s 22
- shl
- ldloc.1
- ldc.i4.s 10
- shr.un
- or
- stloc.1 // stores b
- ldloc.1 // loads b
- ldloc.2
- add
- stloc.1
the second version's:
- ldloc.1
- ldloc.3
- ldloc.0
- xor
- ldloc.2
- and
- ldloc.0
- xor
- ldsfld unsigned int32[] MD5AddOptimization3::K
- ldc.i4.7
- ldelem.u4
- add
- ldarg.0
- ldfld unsigned int32[] MD5AddOptimization3::buff
- ldc.i4.7
- ldelem.u4
- add
- add
- stloc.1
- ldloc.1
- ldc.i4.s 22
- shl
- ldloc.1
- ldc.i4.s 10
- shr.un
- or
- // store, load eliminated
- ldloc.2
- add
- stloc.1
I thought this was weird, because I assumed that the compiler might be able to find these kinds of unnecessary operations, but I guess it is harder to locate them than it seems. Especially since a wrong optimization might end up with broken code.
A weird thing is: I just did some testing on my old, old i586 - and this optimization I described here actually decreases performances under some cirumstances! Obviously the lesson learned is: Never trust "optimizations" without testing them!
Well, I'll soon write about more safe optimizations I found. But this is for sure again: Optimizing is all about trial and error. There is almost no way to tell if anything might perform better or worse.

I’d like to see the md5 source code implemetation after the optimization steps.
could you upload it.
thanks
Comment on April 29, 2009 @ 10:56:29
Do you specifically need the safe optimizations? Or are the unsafe optimizations enough?
Comment on April 30, 2009 @ 17:48:23