Microoptimization

master
Inga 🏳‍🌈 7 years ago
parent d8ef0310df
commit 8552a17b21
  1. 18
      dotnet/WhiteRabbit.UnmanagedBridge/WhiteRabbit.UnmanagedBridge.cpp
  2. 2
      dotnet/WhiteRabbit/Constants.cs
  3. 5
      dotnet/WhiteRabbit/MD5Digest.cs
  4. 46
      dotnet/WhiteRabbit/PhraseSet.cs
  5. 2
      dotnet/WhiteRabbit/PrecomputedPermutationsGenerator.cs

@ -9,17 +9,19 @@ void WhiteRabbitUnmanagedBridge::MD5Unmanaged::ComputeMD5(unsigned __int32 * inp
{ {
#if AVX2 #if AVX2
md5(input + 0 * 8 * 8, output + 0 * 8); md5(input + 0 * 8 * 8, output + 0 * 8);
md5(input + 1 * 8 * 8, output + 0 * 8);
#elif SIMD #elif SIMD
md5(input + 0 * 8 * 4, output + 0 * 4); md5(input + 0 * 8 * 4, output + 0 * 4);
md5(input + 1 * 8 * 4, output + 1 * 4); md5(input + 1 * 8 * 4, output + 1 * 4);
if (input[2 * 8 * 4] != 0)
{
md5(input + 2 * 8 * 4, output + 0 * 4);
md5(input + 3 * 8 * 4, output + 1 * 4);
}
#else #else
md5(input + 0 * 8, output + 0); for (int i = 0; i < 16; i++)
md5(input + 1 * 8, output + 1); {
md5(input + 2 * 8, output + 2); md5(input + i * 8, output + i);
md5(input + 3 * 8, output + 3); }
md5(input + 4 * 8, output + 4);
md5(input + 5 * 8, output + 5);
md5(input + 6 * 8, output + 6);
md5(input + 7 * 8, output + 7);
#endif #endif
} }

@ -2,6 +2,6 @@
{ {
internal class Constants internal class Constants
{ {
public const int PhrasesPerSet = 8; public const int PhrasesPerSet = 16;
} }
} }

@ -12,7 +12,10 @@
var result = new uint[Constants.PhrasesPerSet]; var result = new uint[Constants.PhrasesPerSet];
fixed (uint* resultPointer = result) fixed (uint* resultPointer = result)
{ {
MD5Unmanaged.ComputeMD5((uint*)input.Buffer, resultPointer); fixed (long* inputBuffer = input.Buffer)
{
MD5Unmanaged.ComputeMD5((uint*)inputBuffer, resultPointer);
}
} }
return result; return result;

@ -3,34 +3,46 @@
using System.Diagnostics; using System.Diagnostics;
// Anagram representation optimized for MD5 // Anagram representation optimized for MD5
internal unsafe struct PhraseSet internal struct PhraseSet
{ {
public fixed long Buffer[4 * Constants.PhrasesPerSet]; public long[] Buffer;
public PhraseSet(Word[] words, long[] permutations, int offset, int numberOfCharacters) public unsafe PhraseSet(Word[] words, long[] permutations, int offset, int numberOfCharacters)
{ {
Debug.Assert(numberOfCharacters + words.Length - 1 < 27); Debug.Assert(numberOfCharacters + words.Length - 1 < 27);
this.Buffer = new long[4 * Constants.PhrasesPerSet];
fixed (long* bufferPointer = this.Buffer) fixed (long* bufferPointer = this.Buffer)
{ {
long* longBuffer = (long*)bufferPointer; long* longBuffer = (long*)bufferPointer;
int numberOfWords = words.Length; int numberOfWords = words.Length;
for (var i = 0; i < Constants.PhrasesPerSet; i++)
fixed (long* permutationsPointer = permutations)
{ {
var permutation = permutations[offset + i]; var currentPermutationPointer = permutationsPointer + offset;
var cumulativeWordOffsetX4 = 0; for (var i = 0; i < Constants.PhrasesPerSet; i++, currentPermutationPointer++)
for (var j = 0; j < numberOfWords; j++)
{ {
var currentWord = words[permutation & 15]; var permutation = *currentPermutationPointer;
permutation = permutation >> 4; if (permutation == 0)
longBuffer[0] |= currentWord.Buffers[cumulativeWordOffsetX4 + 0]; {
longBuffer[1] |= currentWord.Buffers[cumulativeWordOffsetX4 + 1]; continue;
longBuffer[2] ^= currentWord.Buffers[cumulativeWordOffsetX4 + 2]; }
longBuffer[3] ^= currentWord.Buffers[cumulativeWordOffsetX4 + 3];
cumulativeWordOffsetX4 += currentWord.LengthX4; var cumulativeWordOffsetX4 = 0;
} for (var j = 0; j < numberOfWords; j++)
{
var currentWord = words[permutation & 15];
permutation = permutation >> 4;
longBuffer[0] |= currentWord.Buffers[cumulativeWordOffsetX4 + 0];
longBuffer[1] |= currentWord.Buffers[cumulativeWordOffsetX4 + 1];
longBuffer[2] ^= currentWord.Buffers[cumulativeWordOffsetX4 + 2];
longBuffer[3] ^= currentWord.Buffers[cumulativeWordOffsetX4 + 3];
cumulativeWordOffsetX4 += currentWord.LengthX4;
}
longBuffer += 4; longBuffer += 4;
}
} }
var length = numberOfCharacters + numberOfWords - 1; var length = numberOfCharacters + numberOfWords - 1;
@ -51,7 +63,7 @@
} }
} }
public byte[] GetBytes(int number) public unsafe byte[] GetBytes(int number)
{ {
Debug.Assert(number < Constants.PhrasesPerSet); Debug.Assert(number < Constants.PhrasesPerSet);

@ -29,7 +29,7 @@
return original; return original;
} }
return original.Concat(Enumerable.Repeat(original[0], chunkSize - (original.Length % chunkSize))).ToArray(); return original.Concat(Enumerable.Repeat(default(T), chunkSize - (original.Length % chunkSize))).ToArray();
} }
private static long FormatPermutation(PermutationsGenerator.Permutation permutation) private static long FormatPermutation(PermutationsGenerator.Permutation permutation)

Loading…
Cancel
Save