0

I need to execute one method with different parameters in parallel (using c#).

I use instructions from here:

http://www.codeproject.com/Articles/189374/The-Basics-of-Task-Parallelism-via-C

but in place of Sum(100), Sum(200), Sum(300) I want execute my a bit more complex method Oracle(JIBitArray bits, int rounds, int[] weak_bits_positions).

Code snippet of Grain class:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GrainApproximations
{
    class Grain
    {
        JIBitArray NFSR;
        JIBitArray LFSR;

        JIBitArray key;
        const int keysize = 128;

        JIBitArray iv;
        const int ivsize = 96;

        public void Init(JIBitArray key, JIBitArray iv, int rounds)
        {
            this.key = key;
            this.iv = iv;

            NFSR = new JIBitArray(keysize);
            LFSR = new JIBitArray(keysize);

            /* load registers */
            //fill NFSR bits with key bits
            for (int i = 0; i < keysize; ++i)
            {
                NFSR.Set(i, this.key.Get(i));
            }

            for (int i = 0; i < ivsize; ++i)
            {
                LFSR.Set(i, this.iv.Get(i));
            }

            //96 < i < 128 bits of LFSR - filling with 1
            for (int i = ivsize; i < keysize; i++)
            {
                LFSR.Set(i, true);
            }

            /* do initial clockings */
            bool outbit;
            bool Lbit;
            bool Nbit;

            for (int i = 0; i < rounds; ++i)
            {
                outbit = grain_keystream();

                Lbit = LFSR.Get(127);
                Nbit = NFSR.Get(127);

                LFSR.Set(127, outbit ^ Lbit);
                NFSR.Set(127, outbit ^ Nbit);
            }

        }

        private bool grain_keystream()
        {
            bool outbit = NFSR.Get(2) ^ NFSR.Get(15) ^ NFSR.Get(36) ^     NFSR.Get(45) ^ NFSR.Get(64) ^ NFSR.Get(73) ^ NFSR.Get(89) ^ LFSR.Get(93) ^ (NFSR.Get(12) & LFSR.Get(8)) ^ (LFSR.Get(13) & LFSR.Get(20)) ^ (NFSR.Get(95) & LFSR.Get(42)) ^ (LFSR.Get(60) & LFSR.Get(79)) ^ (NFSR.Get(12) & NFSR.Get(95) & LFSR.Get(95));
            bool Nbit = LFSR.Get(0) ^ NFSR.Get(0) ^ NFSR.Get(26) ^ NFSR.Get(56) ^ NFSR.Get(91) ^ NFSR.Get(96) ^ (NFSR.Get(3) & NFSR.Get(67)) ^ (NFSR.Get(11) & NFSR.Get(13)) ^ (NFSR.Get(17) & NFSR.Get(18)) ^ (NFSR.Get(27) & NFSR.Get(59)) ^ (NFSR.Get(40) & NFSR.Get(48)) ^ (NFSR.Get(61) & NFSR.Get(65)) ^ (NFSR.Get(68) & NFSR.Get(84));
            bool Lbit = LFSR.Get(0) ^ LFSR.Get(7) ^ LFSR.Get(38) ^ LFSR.Get(70) ^ LFSR.Get(81) ^ LFSR.Get(96);

            NFSR = NFSR.ShiftLeft(1);
            LFSR = LFSR.ShiftLeft(1);

            NFSR.Set(keysize - 1, Nbit);
            LFSR.Set(keysize - 1, Lbit);

            return outbit;
        }

        public JIBitArray Generate_Gamma_Bits(int length_in_bits)
        {
            JIBitArray ret = new JIBitArray(length_in_bits);

            for (int i = 0; i < length_in_bits; i++)
            {
                ret.Set(i, grain_keystream());
            }
            return ret;

        }

        public JIBitArray Oracle(JIBitArray bits, int rounds, int[] weak_bits_positions)
        {
            JIBitArray key_bits = bits.SubJIBitArray(0, 128);
            JIBitArray iv_bits = bits.SubJIBitArray(128, 96);

            JIBitArray[] L_subspace = Build_L_subspace(iv_bits, weak_bits_positions);

            for (int i = 0; i < weak_bits_positions.Length; i++)
            {
                iv_bits.Set(weak_bits_positions[i], false);
            }

            int count = 0;

            bool outbit = false;
            JIBitArray gamma = new JIBitArray(1);

            for (int i = 0; i < L_subspace.Length; i++)
            {
                Init(key_bits, iv_bits.Xor(L_subspace[i]), rounds);
                outbit = Generate_Gamma_Bits(1).Get(0);

                if (outbit)
                {
                    count++;
                }

                //Console.ReadLine();
            }

            Console.Write("oracle:");
            Console.Write(count % 2);

            return count % 2 == 1 ? new JIBitArray(new bool[] { true }) : new JIBitArray(new bool[] { false });
        }

        public JIBitArray[] Build_L_subspace(JIBitArray iv_bits, int[] weak_bits)
        {
            JIBitArray[] L_subspace = new JIBitArray[(int)Math.Pow((double)2, (double)weak_bits.Length)];
            JIBitArray[] vectors = VectorTable(weak_bits.Length);

            for (int i = 0; i < (int)Math.Pow((double)2, (double)weak_bits.Length); i++)
            {
                L_subspace[i] = new JIBitArray(iv_bits.Count);

                for (int j = 0; j < weak_bits.Length; j++)
                {
                    L_subspace[i].Set(weak_bits[j], vectors[i].Get(j));
                }
            }

            return L_subspace;
        }

        //build table of all vectors of k variables
        public static JIBitArray[] VectorTable(int k)
        {
            int rows = (int)Math.Pow((double)2, (double)k);
            bool[] tmp = new bool[k];
            JIBitArray[] result = new JIBitArray[rows];
            string x = string.Empty;
            char[] characters = new char[0];
            bool[] vector = new bool[0];

            for (int i = 0; i < rows; i++)
            {
                x = Convert.ToString(i, 2);
                x = x.PadLeft(k, '0');
                characters = x.ToCharArray();
                vector = new bool[characters.Length];

                for (int j = 0; j < characters.Length; j++)
                {
                    if (characters[j] == '1')
                    {
                        vector[j] = true;
                    }
                    else
                    {
                        vector[j] = false;
                    }
                }
                result[i] = new JIBitArray(vector);
            }
            return result;
        }           
    }
}

JIBitArray - it's a modified version of standart .NET collection BitArray:

http://www.codeproject.com/Articles/14430/My-BitArray-Class

In Main method I try to execute:

Grain grain = new Grain();
Task<bool[]> parent = new Task<bool[]>(() =>
        {
            var results = new bool[5];   // Create an array for the results

            // This tasks creates and starts 3 child tasks

            for (int i = 0; i < results.Length; i++)
            {
                new Task(() => results[i] = grain.Oracle(bits[i], rounds, weak_bits).Get(0), TaskCreationOptions.AttachedToParent).Start();
            }

            // Returns a reference to the array
            // (even though the elements may not be initialized yet)
            return results;
        });

        // When the parent and its children have
        // run to completion, display the results
        var cwt = parent.ContinueWith(parentTask =>
                            Array.ForEach(parentTask.Result, Console.WriteLine));

        // Start the parent Task so it can start its children
        parent.Start();

        cwt.Wait(); // For testing purposes

where bits - it's an array of 5 different JIBitArray binary vectors with 128 + 96 = 224 bits length.

But I get System.AggregateException and System.ArgumentOutOfRangeException, while computations.

I use TPL because I need to execute 2^20 tasks with different input parameters (bits has 2^20 elements)

Can somebody explain what is wrong?

5
  • Hi! That's a lot of code. Are the exceptions due to the parallel processing? How many tasks are running simultaneously? Are the algorithms tested and do they work in a non-parallel environment? Maybe you should pinpoint the problem a bit more to get some good answers here ;-) Commented Jun 14, 2015 at 13:29
  • Oracle(JIBitArray bits, int rounds, int[] weak_bits_positions) - works correctly in non-parallel. I am forced to use TPL because evaluation of 2^20 vectors by Oracle method takes about 7 hours Commented Jun 14, 2015 at 13:35
  • One issue is that you are not capturing the loop variable i. By the time the inner task executes, i is already 5. Commented Jun 14, 2015 at 14:01
  • you're getting an exception because one of your threads is throwing an exception; it has nothing to do with the parallelism. Try running the same code serially and find out which iteration is broken. Commented Jun 14, 2015 at 14:30
  • 1
    Tasks aren't threads. By creating so many tasks you simply end up wasting resources and causing delays. Each task execution has overhead, you should create tasks that are chunky enough to justify the it. The code has little in common with the article - eg why the cold tasks? Why so many? Perhaps you should try using PLINQ first to see how parallel execution performs. PLINQ performs partitioning of the data and scheduling of tasks automagically -things any parallel code should do Commented Jun 15, 2015 at 12:58

1 Answer 1

1

One issue is that you are not capturing the loop variable i. By the time the inner task executes, i is already 5.

But you also do not appear to be waiting for the inner task results. Why not make the inner task a Task<bool> so you can get (and wait for) its result?

Also, as written your parent task is utterly pointless, just use a method if all you want to do is start some other Tasks (you have no long-running computation in there). If you wanted it to be useful it would wait for the child Tasks to complete and then return the combined result.

Using Parallel.ForEach would make this code much simpler and more likely to achieve what you are trying to do.

Sign up to request clarification or add additional context in comments.

3 Comments

Yes I know about Parallel.For loop. But ufortunatelly It gives the same exeptions....
It seems to me that there are some restrictions to methods (mean - restrictions to operations inside method), that can be put into Parallel.For construction.
While using Parallel.For, the first iteration is normal (computaion of the first out bit is correct) but It breaks on the second iteration. google doesn't help much...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.