i trying convert following collatz conjecture algorithm from:
   public class collatzconjexture     {         public static int calculate(int startindex, int maxsequence)         {             int chainlength = 0;             int key = 0;             bool continutecalulating = true;             int longestchain = 0;             int64 remainder = 0;              (int = startindex; <= maxsequence; i++)             {                 chainlength = 1;                 remainder = i;                 continutecalulating = true;                  while (continutecalulating)                 {                     remainder = calculatecollatzconjecture(remainder);                     if (remainder == 1)                         continutecalulating = false;                      chainlength += 1;                 }                  if (chainlength > longestchain)                 {                     longestchain = chainlength;                     key = i;                 }             }              return key;         }          private static int64 calculatecollatzconjecture(int64 number)         {             if (number % 2 == 0)                 return number / 2;             else                 return (3 * number) + 1;         }     }  
  to instead use .net 4.0 parallel.for :
  int chainlength = 0;             int key = 0;             bool continutecalulating = true;             int longestchain = 0;             int64 remainder = 0;              int[] nums = enumerable.range(1, 1500000).toarray();             long total = 0;              // use type parameter make subtotal long, not int             parallel.for<int>(1, nums.length, () => 1, (j, loop, subtotal) =>             {                 remainder = j;                  while (continutecalulating)                 {                     remainder = calculatecollatzconjecture(remainder);                     if (remainder == 1)                         continutecalulating = false;                      chainlength += 1;                 }                  if (chainlength > longestchain)                 {                     longestchain = chainlength;                     key = j;                 }                 return key;               },                 (x) => interlocked.add(ref key, x)             ); 
  i have feeling i'm not far it, famous last words.
  thanks in advance.
        
  your problem don't want use parallel.for in instance because have array (nums) iterate over, calls parallel.foreach. however, array created enumerable.range , don't use anything, best way asparallel , linq (plinq):
  public static class collatzconjexture2 {     public static int calculate(int startindex, int maxsequence)     {         var nums = enumerable.range(startindex, maxsequence);         return nums.asparallel()                     // compute length of chain each number                    .select(n => new { key = n, len = collatzchainlength(n) })                     // find longest chain                    .aggregate((max, cur) => cur.len > max.len ||                     // make sure have lowest key longest chain                       max.len == cur.len && cur.key < max.key ? cur : max)                     // number produced longest chain                    .key;     }      private static int collatzchainlength(int64 number)     {         int chainlength;         (chainlength = 1; number != 1; chainlength++)             number = (number & 1) == 0 ? number >> 1 : number * 3 + 1;         return chainlength;     } } 
  this method twice fast on computer serial implementation. note optimized main loop computation inline rather calling function , uses bitwise math instead of multiplying , dividing. made twice fast again. compiling x64 instead of x86 made more twice fast.
       
   
Comments
Post a Comment