Brothers In Code

...a serious misallocation of .net resources

Parallel.For - Multithreading Made Easy

I was using nunit to make sure a checkbits/signing algorithm was doing what it was supposed to do. Like everything in cryptography it was slow. The following loop took more than 16 seconds:


      for (int i = 0; i < 10; i++)
      {
        var value = (UInt64)rng.Next((Int32)cipher.MaximumSequence);
        ulong? lastHackedValue = null;
        //for all the checkbit combinations...
        for (int j = 1; j < Math.Pow(2, cipher.CheckBits) - 1; j++)
        {
          //move the checkbits over to the correct spot
          var signature = (UInt64)j << cipher.SequenceBits;
          var hackedValue = value + signature;
          try
          {
            cipher.Unsign(hackedValue);
            if (lastHackedValue == null)
              lastHackedValue = hackedValue;
            else
              Assert.Fail("Too many successful cracks for value {0}.  Hacked Value 1:{1}, Hacked Value 2:{2}", 
                i, lastHackedValue, hackedValue);
          }
          catch(ApplicationException ex)
          {
            Assert.That(ex.Message == "Invalid signature");
          }
        }
      }

I tried using the Parallel class – sending my cpu utilization from 12 to 100% and I got it down to 5 seconds:


        var parallelresult = Parallel.For(0, 10, i =>
        {
    //...same for loo
    });


I noticed that assertion failures were not being displayed in nunit correctly.  It turned out the .For call was wrapping them in an AggregateException so I wrapped the code like this:

    try
      {
        var parallelresult = Parallel.For(0, 10, i =>
        {
    ...
        });
      }
      catch(AggregateException ex)
      {
        if(ex.InnerException is AssertionException)
        {
          throw ex.InnerException;
        }
        else
        {
          throw ex;
        }
 
      }

Comments are closed