Optimization: reduced number of pinning operations

master
Inga 🏳‍🌈 7 years ago
parent 5a0026ff80
commit 332188d3e9
  1. 8
      README.md
  2. 47
      dotnet/WhiteRabbit/PhraseSet.cs
  3. 22
      dotnet/WhiteRabbit/StringsProcessor.cs

@ -47,10 +47,10 @@ Number of words|Time to check all anagrams no longer than that|Time to solve "ea
---------------|----------------------------------------------|-------------------------|-----------------------------------|-------------------------|---------------------------------------------
3|0.04s||||4560
4|0.45s|||0.08s|7,431,984
5|10.4s|0.15s|0.06s|0.3s|1,347,437,484
6|5.5 minutes|1s|0.2s|2.5s|58,405,904,844
7|81 minutes|5.7s|0.8s|16.1s|1,070,307,744,114
8|21.5 hours|21s|2.3s|65s|10,893,594,396,594
5|10s|0.15s|0.06s|0.29s|1,347,437,484
6|5 minutes|0.9s|0.2s|2.3s|58,405,904,844
7|81 minutes|5.1s|0.7s|14.5s|1,070,307,744,114
8|21.5 hours|19s|2s|59s|10,893,594,396,594
9||2.5 minutes|13s|9.5 minutes|70,596,864,409,954
10||5 minutes|21s|17.5 minutes|314,972,701,475,754

@ -1,7 +1,9 @@
namespace WhiteRabbit
{
using System;
using System.Diagnostics;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using WhiteRabbitUnmanagedBridge;
@ -29,9 +31,9 @@
}
}
public unsafe void FillPhraseSet(PhraseSet initial, Word[] allWords, int[] wordIndexes, ulong[] permutations, int permutationOffset)
public unsafe void ProcessPermutations(PhraseSet initialPhraseSet, Word[] allWords, int[] wordIndexes, ulong[] permutations, Vector<uint> expectedHashes, Action<byte[], uint> action)
{
fixed (uint* bufferPointer = this.Buffer, initialBufferPointer = initial.Buffer)
fixed (uint* bufferPointer = this.Buffer, initialBufferPointer = initialPhraseSet.Buffer)
{
fixed (ulong* permutationsPointer = permutations)
{
@ -39,33 +41,32 @@
{
fixed (Word* allWordsPointer = allWords)
{
MD5Unmanaged.FillPhraseSet(
(ulong*)initialBufferPointer,
(ulong*)bufferPointer,
(ulong*)allWordsPointer,
wordIndexesPointer,
permutationsPointer + permutationOffset,
wordIndexes.Length);
for (var i = 0; i < permutations.Length; i += Constants.PhrasesPerSet)
{
MD5Unmanaged.FillPhraseSet(
(ulong*)initialBufferPointer,
(ulong*)bufferPointer,
(ulong*)allWordsPointer,
wordIndexesPointer,
permutationsPointer + i,
wordIndexes.Length);
MD5Unmanaged.ComputeMD5(bufferPointer);
for (var j = 0; j < Constants.PhrasesPerSet; j++)
{
if (Vector.EqualsAny(expectedHashes, new Vector<uint>(bufferPointer[j * 8 + 7])))
{
action(this.GetBytes(j), bufferPointer[j * 8 + 7]);
}
}
}
}
}
}
}
}
public unsafe void ComputeMD5()
{
fixed (uint* inputBuffer = this.Buffer)
{
MD5Unmanaged.ComputeMD5(inputBuffer);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public uint GetMD5(int number)
{
return this.Buffer[number * 8 + 7];
}
public unsafe byte[] GetBytes(int number)
{
Debug.Assert(number < Constants.PhrasesPerSet);

@ -130,21 +130,13 @@
var wordsVariants = this.ConvertVectorsToWordIndexes(sum);
foreach (var wordsArray in Flattener.Flatten(wordsVariants))
{
//Console.WriteLine(new string(wordsArray.SelectMany(wordIndex => this.AllWords[wordIndex].Original).Select(b => (char)b).ToArray()));
var permutations = PrecomputedPermutationsGenerator.HamiltonianPermutations(wordsArray.Length, permutationsFilter);
for (var i = 0; i < permutations.Length; i += Constants.PhrasesPerSet)
{
phraseSet.FillPhraseSet(initialPhraseSet, this.AllWords, wordsArray, permutations, i);
phraseSet.ComputeMD5();
for (var j = 0; j < Constants.PhrasesPerSet; j++)
{
if (Vector.EqualsAny(expectedHashes, new Vector<uint>(phraseSet.GetMD5(j))))
{
action(phraseSet.GetBytes(j), phraseSet.GetMD5(j));
}
}
}
phraseSet.ProcessPermutations(
initialPhraseSet,
this.AllWords,
wordsArray,
PrecomputedPermutationsGenerator.HamiltonianPermutations(wordsArray.Length, permutationsFilter),
expectedHashes,
action);
}
}
}

Loading…
Cancel
Save