Parallel Computing Example

I’ve always wondered how parallel computing works. One of my fascinations with computers has been the ability to seem like it’s doing more than one thing at once. Granted the computer is doing one thing after another really really quick. So it would be safe to say that parallel computing is doing more than one thing one item at a time. With multi-processor and multi- core computers being so prevalent in today’s world this concept is really fascinating to me.

What this program does is run two programs that do the same basic thing. Find all the prime numbers of a random range of numbers a specified number of times. I chose a prime number calculation because I wanted to put some kind of load on the CPU for X amount of times.

ParallelProgram ParallelSolution

One program runs with the TimeKeeper class and reports the elapsed time to finish said program. The second program simply runs the prime number loop a specified number of times. No time keeping being done. The number of times the test is run via the constructor calls. This is just a simple console program doing a proof of concept thing for me. No real user interface, logic, logging, and very basic error checking are being done.

The two main methods being run from Program.cs are runWithTimeKeeper() and testPerformance().

Again, if you want to look at the program source on your own machine you can download it.

 

Conversion.cs code contents

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

namespace _3rdModule
{
    public static class Conversion
    {
        // Public methods.
        //
        public static int ConvertUserInput(string value)
        {
            return _convertUserInput(value);
        }

        // Private methods.
        //
        private static int _convertUserInput(string value)
        {
            int convertedString;
            if (int.TryParse(value, out convertedString))
                return convertedString;
            else
                return 0;
        }
    }
}

This class is really simple. All this is doing it taking the users input and attempting to convert it into a number for use.

 

DoMath.cs code contents

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

namespace _3rdModule
{
    public static class DoMath
    {
        // Public Methods
        //
        public static bool IsPrime(int number)
        {
            return _isPrime(number);
        }

        // Private Methods
        //
        private static bool _isPrime(int number)
        {
            bool result = true;
            for (long i = 2; i < number; i++)
            {
                if (number % i == 0)
                {
                    result = false;
                    break;
                }
            }
            return result;
        }
    }
}

This class is taking a number and finding all of the prime numbers that the specified number can have.

 

TimeKeeper.cs code contents

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace _3rdModule
{
    public class TimeKeeper
    {
        public TimeSpan Measure(Action action)
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();
            action();
            return watch.Elapsed;
        }
    }
}

This is a simple time keeper class that uses the stop watch class to measure elapsed time. This is used in one of the programs to measure how long it took to find all the prime numbers a specified amount of time.

 

TestPerformance.cs code contents

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

namespace _3rdModule
{
    public class TestPerformance
    {
        // Private Fields
        //
        private Random _random;

        // Public Read-Only Fields
        //
        public List<int> RandomIntList { get; private set; }

        // Constructors
        //
        public TestPerformance()
        {
            _random = new Random();
            RandomIntList = new List<int>();
        }

        // Public Methods
        //
        // Default method that adds random numbers to a list a random number of times.
        // This method can take a really long time to run. Use with caution.
        public void AddToIntList()
        {
            int randomTimesToTest = _random.Next(1, 1234);
            int randomNumberToAdd;
            
            for (int i = 0; i < randomTimesToTest; i++)
            {
                randomNumberToAdd = _random.Next(1, 123456789);
                RandomIntList.Add(randomNumberToAdd);
            }
        }

        // Overloaded method that adds random numbers to a list based on how many times the user specifies.
        public void AddToIntList(int timeToTest)
        {
            int randomNumberToAdd;
            for (int i = 0; i < timeToTest; i++)
            {
                randomNumberToAdd = _random.Next(1, 123456789);
                RandomIntList.Add(randomNumberToAdd);
            }
        }
    }
}

This class is where things start to come together. It implements private, public read-only fields, and public methods.

The constructor creates the random number private field and the read-only random number list.

The public method AddToIntList is overloaded. One accepts no parameters. The other accepts an int value to specify how many times the for loop. Both loops add random numbers to the read-only list.

These numbers will be used in the prime number calculations.

The method with no parameters has a random specified number of times the for loop runs.

The method with a parameter takes said parameter and executes that for loop said number of times.

 

Program.cs code contents

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;

namespace _3rdModule
{       
    class Program
    {
        static void Main(string[] args)
        {          
            // Since the programs don't depend on one another run in parallel.
            Parallel.Invoke(() => 
            {
                // Run one program.
                runWithTimeKeeper();

            }, () =>
            {
                // Run another program.
                testPerformance("5");
            }
            );
            Console.ReadLine();
        }

        // Private Methods.
        //

        // Method used to test performance with a random set of numbers and calculate if those numbers are prime.
        private static void testPerformance()
        {
            TestPerformance testAppWithRandomInts = new TestPerformance();
            testAppWithRandomInts.AddToIntList();

            foreach (int item in testAppWithRandomInts.RandomIntList)
            {
                Console.WriteLine("Number Tested: {0}", item);
                Console.WriteLine("Is A Prime Number: {0}", DoMath.IsPrime(item));
                Console.WriteLine();
            }
            Console.WriteLine("Total Numbers Tested: {0}", testAppWithRandomInts.RandomIntList.Count);
        }

        // Method used to test performance with a user specified amount of numbers and calculate if those numbers are prime.
        private static void testPerformance(string timesToTest)
        {
            Console.WriteLine();

            // Convert the string into a number.
            int numberOfTests = Conversion.ConvertUserInput(timesToTest);

            TestPerformance testSpecificTimes = new TestPerformance();
            testSpecificTimes.AddToIntList(numberOfTests);

            foreach (int item in testSpecificTimes.RandomIntList)
            {
                Console.WriteLine("Number Tested: {0}", item);
                Console.WriteLine("Is A Prime Number: {0}", DoMath.IsPrime(item));
                Console.WriteLine();
            }
            Console.WriteLine("Total Numbers Tested: {0}", testSpecificTimes.RandomIntList.Count);
        }

        // Method that runs with a time keeper started.
        private static void runWithTimeKeeper()
        {
            TimeKeeper timeKeeper = new TimeKeeper();
            var elapsedTime = timeKeeper.Measure(() => testPerformance("7"));
            Console.WriteLine("Time To Run: {0}", elapsedTime);
        }
    }
}

First thing you will notice is the use of the Parallel.Invoke() method. You will calls to the two programs.

The runWithTimeKeeper() method makes the call that uses the stopwatch to calculate the elapsed time to finish the program while running the random number generator loop 7 times. Yes this is hard coded I know. This isn’t a production application.. šŸ™‚

The testPerfomance() method call is specifying the amount of times the random number loops are to run.

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s