From 4f2dbe10522d55003c87c21566070f2305dd889b Mon Sep 17 00:00:00 2001 From: inga-lovinde <52715130+inga-lovinde@users.noreply.github.com> Date: Thu, 6 Apr 2017 13:40:28 +0300 Subject: [PATCH] PhraseSet constructor refactored to use SIMD instead of branching (slow version) --- dotnet/WhiteRabbit/PhraseSet.cs | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/dotnet/WhiteRabbit/PhraseSet.cs b/dotnet/WhiteRabbit/PhraseSet.cs index 6bed70a..12fe109 100644 --- a/dotnet/WhiteRabbit/PhraseSet.cs +++ b/dotnet/WhiteRabbit/PhraseSet.cs @@ -1,8 +1,16 @@ -namespace WhiteRabbit +using System.Numerics; + +namespace WhiteRabbit { // Anagram representation optimized for MD5 internal unsafe struct PhraseSet { + private const int WordIndexMask = unchecked((int)(((uint)-1) << 16)); + + private const int WordIndexIncrement = ((int)1) << 16; + + private const int CharIndexMask = ((int)1 << 16) - 1; + public fixed uint Buffer[8 * Constants.PhrasesPerSet]; public PhraseSet(byte[][] words, int[][] permutations, int offset, int numberOfCharacters) @@ -15,22 +23,20 @@ { var permutation = permutations[offset + i]; var startPointer = bufferPointer + i * 8; - byte[] currentWord = words[permutation[0]]; - var j = 0; - var wordIndex = 0; var currentPointer = (byte*)startPointer; byte* lastPointer = currentPointer + length; + + int currentState = 0; // wordIndex << 16 + charIndex + byte[] currentWord = words[permutation[0]]; + for (; currentPointer < lastPointer; currentPointer++) { - if (j >= currentWord.Length) - { - j = 0; - wordIndex++; - currentWord = words[permutation[wordIndex]]; - } - - *currentPointer = currentWord[j]; - j++; + currentWord = words[permutation[currentState >> 16]]; + *currentPointer = currentWord[(currentState & CharIndexMask)]; + + currentState++; + var nextStateNextWord = new Vector((currentState + WordIndexIncrement) & WordIndexMask); + currentState = Vector.ConditionalSelect(Vector.GreaterThanOrEqual(new Vector(currentState & CharIndexMask), new Vector(currentWord.Length)), nextStateNextWord, new Vector(currentState))[0]; } *currentPointer = 128;