Основы параллельного программирования с использованием Visual Studio 2010

Создание приложения с распараллеливанием данных

Разбить на страницы
Показывать лекцию целиком

Parallel.For

  • Создадим консольное приложение и назовем его, к примеру, "ParallelForApplication": (рис 10.1)
  • Создадим метод MaxNumber(), который бы находил максимальное случайно-сгенерированное число:
    static int Max=1;
            static void Maxnumber(int c)
            {
                Random rnd = new Random();
                int v = rnd.Next(0, c);
               
                if (Max < v)
                {
                    Max = v;
                }
            }
  • В методе Main() создадим цикл, который будет передавать значения переменной i в метод Maxnumber:
    for (int i = 1; i <= 10000000; i++)
          {
              Maxnumber(i);
          }
          Console.WriteLine("Максимальное число: {0} ",Max);
          Console.ReadLine();
  • Запустим программу. В результате, через некоторое время, отобразиться результат: (рис 10.2)

    Листинг кода программы:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    namespace ParallelForApplication
    {
        class Program
        {
            static int Max=1;
            static void Maxnumber(int c)
            {
                Random rnd = new Random();
                int v = rnd.Next(0, c);
               
                if (Max < v)
                {
                    Max = v;
                }
           
            }
            static void Main(string[] args)
            {
               for (int i = 1; i <= 10000000; i++)
                {
                    Maxnumber(i);
                }
                Console.WriteLine("Максимальное число: {0} ",Max);
                Console.ReadLine();
            }
        }}
  • Теперь для того, что бы посмотреть, сколько по времени отрабатывается метод Maxnumber(), добавим в код строчки:
    System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
          for (int i = 1; i <= 10000000; i++)
          {
              Maxnumber(i);
          }
          long elapsed = sw.ElapsedMilliseconds;
          Console.WriteLine("Время выполнения алгоритма в миллисекундах: {0}", elapsed);
          Console.WriteLine("Максимальное число: {0} ",Max);
          Console.ReadLine();
  • Запустим программу. В результате отобразиться следующее: (рис 10.3)

    Примечание. Как видно из результата, время выполнения алгоритма составляет ~50 секунд.

  • Подключим директиву, для того что бы использовать цикл Parallel.For:
    using System.Threading.Tasks
  • Теперь заменим цикл for на Parallel.For, для того, что бы метод Maxnumber, выполнялся не последовательно, а асинхронно:
    Parallel.For(1, 10000000, i =>
          {
              Maxnumber(i);
          });
  • Запустим программу. В результате отобразится следующее: (рис 10.4)

    Примечание. Как видно из результата выполнения программы, время выполнения распараллеленного метода Maxnumber(), составит приблизительно 31 секунду.

    Листинг кода программы:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace ParallelForApplication
    {
        class Program
        {
            static int Max=1;
            static void Maxnumber(int c)
            {
                Random rnd = new Random();
                int v = rnd.Next(0, c);
               
                if (Max < v)
                {
                    Max = v;
                }  
            }
            static void Main(string[] args)
            {
      
                System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
                Parallel.For(1, 10000000, i =>
                {
                    Maxnumber(i);
                });
                long elapsed = sw.ElapsedMilliseconds;
                Console.WriteLine("Время выполнения алгоритма в миллисекундах: {0}", elapsed);
                Console.WriteLine("Максимальное число: {0} ",Max);
                Console.ReadLine();
            }
        }
    }
  • Parallel.Foreach

    В данной части практического занятия будет разработано консольное приложение, которое скачивает содержание Web-страниц, в цикле foreach, и в цикле Parralel.Foreach.

  • Создадим консольное приложение и назовем его, к примеру, ParallelForeachApplication (рис 10.5)
  • Подключаем необходимые директивы:
    using System.Net;
    using System.Threading.Tasks;
  • Инициализируем коллекцию ссылок List<string>:
    List<string> urls =  new List<string>() 
    {"http://intuit.ru",                           
    "http://rbc.ru",                              
    "http://ozon.ru",                            
    "http://google.com",                         
     "http://mail.ru",                         
        "http://lenta.ru"                             
        };
  • Теперь, создадим цикл foreach, в котором бы скачивалась содержание Web-страниц, определенные в списке List<string>:
    System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();        
    
    foreach (string url in urls)            
    {                
    WebClient client = new WebClient();                
    Console.WriteLine("Скачиваем : {0}" , url);
          client.DownloadString(url);            
    }           
     
    long elapsed = sw.ElapsedMilliseconds;
    Console.WriteLine("Затраченное время в миллисекундах: {0}",elapsed);
                sw.Stop();
  • Запустим программу. На экране отобразится результат выполнение алгоритма: (рис 10.6)
  • Далее, создадим аналогичный цикл, который бы скачивал содержание Web-страниц, но в параллельном режиме:
    Console.WriteLine("============================");
          sw.Restart();
          Parallel.ForEach(urls, url =>
          {
              WebClient client = new WebClient();
              Console.WriteLine("Скачиваем : " + url);
              client.DownloadString(url);
          });
          elapsed = sw.ElapsedMilliseconds;
          Console.WriteLine("Затраченное время в миллисекундах: {0}", elapsed);
          sw.Stop();            
    
    Console.ReadLine();
  • Запустим программу. В результате на экране отобразится следующее: (рис 10.7)

    Примечание. Цикл Parallel.Foreach, будет выполняться значительно быстрее т.к. методы, прописанные внутри тела цикла, будут выполняться в несколько потоков.

    Листинг кода программы:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Collections;
    using System.Net;
    using System.Threading.Tasks;
    namespace ParallelForeachApplication
    {
        class Program
        {
            static void Main(string[] args)
            {
         List<string> urls =  new List<string>() { 
    "http://intuit.ru",                                  
    "http://rbc.ru",                                  
    "http://ozon.ru",                                  
    "http://google.com",                                 
    "http://mail.ru",                                 
    "http://lenta.ru"                              
    };            
    System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();        
                    
    foreach (string url in urls)            
    {                
    WebClient client = new WebClient();                
    Console.WriteLine("Скачиваем : {0}" , url);
                    client.DownloadString(url);            
    }           
     
    long elapsed = sw.ElapsedMilliseconds;
    Console.WriteLine("Затраченное время в миллисекундах: {0}",elapsed);
                sw.Stop();
                Console.WriteLine("============================");
                sw.Restart();
                Parallel.ForEach(urls, url =>
                {
                    WebClient client = new WebClient();
                    Console.WriteLine("Скачиваем : " + url);
                    client.DownloadString(url);
                });
                elapsed = sw.ElapsedMilliseconds;
                Console.WriteLine("Затраченное время в миллисекундах: {0}", elapsed);
                sw.Stop();            
    Console.ReadLine();        
    }    
            }
        }
  • Страницы:

    Parallel.For

  • Создадим консольное приложение и назовем его, к примеру, "ParallelForApplication": (рис 10.1)
  • Создадим метод MaxNumber(), который бы находил максимальное случайно-сгенерированное число:
    static int Max=1;
            static void Maxnumber(int c)
            {
                Random rnd = new Random();
                int v = rnd.Next(0, c);
               
                if (Max < v)
                {
                    Max = v;
                }
            }
  • В методе Main() создадим цикл, который будет передавать значения переменной i в метод Maxnumber:
    for (int i = 1; i <= 10000000; i++)
          {
              Maxnumber(i);
          }
          Console.WriteLine("Максимальное число: {0} ",Max);
          Console.ReadLine();
  • Запустим программу. В результате, через некоторое время, отобразиться результат: (рис 10.2)

    Листинг кода программы:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    namespace ParallelForApplication
    {
        class Program
        {
            static int Max=1;
            static void Maxnumber(int c)
            {
                Random rnd = new Random();
                int v = rnd.Next(0, c);
               
                if (Max < v)
                {
                    Max = v;
                }
           
            }
            static void Main(string[] args)
            {
               for (int i = 1; i <= 10000000; i++)
                {
                    Maxnumber(i);
                }
                Console.WriteLine("Максимальное число: {0} ",Max);
                Console.ReadLine();
            }
        }}
  • Теперь для того, что бы посмотреть, сколько по времени отрабатывается метод Maxnumber(), добавим в код строчки:
    System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
          for (int i = 1; i <= 10000000; i++)
          {
              Maxnumber(i);
          }
          long elapsed = sw.ElapsedMilliseconds;
          Console.WriteLine("Время выполнения алгоритма в миллисекундах: {0}", elapsed);
          Console.WriteLine("Максимальное число: {0} ",Max);
          Console.ReadLine();
  • Запустим программу. В результате отобразиться следующее: (рис 10.3)

    Примечание. Как видно из результата, время выполнения алгоритма составляет ~50 секунд.

  • Подключим директиву, для того что бы использовать цикл Parallel.For:
    using System.Threading.Tasks
  • Теперь заменим цикл for на Parallel.For, для того, что бы метод Maxnumber, выполнялся не последовательно, а асинхронно:
    Parallel.For(1, 10000000, i =>
          {
              Maxnumber(i);
          });
  • Запустим программу. В результате отобразится следующее: (рис 10.4)

    Примечание. Как видно из результата выполнения программы, время выполнения распараллеленного метода Maxnumber(), составит приблизительно 31 секунду.

    Листинг кода программы:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace ParallelForApplication
    {
        class Program
        {
            static int Max=1;
            static void Maxnumber(int c)
            {
                Random rnd = new Random();
                int v = rnd.Next(0, c);
               
                if (Max < v)
                {
                    Max = v;
                }  
            }
            static void Main(string[] args)
            {
      
                System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
                Parallel.For(1, 10000000, i =>
                {
                    Maxnumber(i);
                });
                long elapsed = sw.ElapsedMilliseconds;
                Console.WriteLine("Время выполнения алгоритма в миллисекундах: {0}", elapsed);
                Console.WriteLine("Максимальное число: {0} ",Max);
                Console.ReadLine();
            }
        }
    }
  • Parallel.Foreach

    В данной части практического занятия будет разработано консольное приложение, которое скачивает содержание Web-страниц, в цикле foreach, и в цикле Parralel.Foreach.

  • Создадим консольное приложение и назовем его, к примеру, ParallelForeachApplication (рис 10.5)
  • Подключаем необходимые директивы:
    using System.Net;
    using System.Threading.Tasks;
  • Инициализируем коллекцию ссылок List<string>:
    List<string> urls =  new List<string>() 
    {"http://intuit.ru",                           
    "http://rbc.ru",                              
    "http://ozon.ru",                            
    "http://google.com",                         
     "http://mail.ru",                         
        "http://lenta.ru"                             
        };
  • Теперь, создадим цикл foreach, в котором бы скачивалась содержание Web-страниц, определенные в списке List<string>:
    System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();        
    
    foreach (string url in urls)            
    {                
    WebClient client = new WebClient();                
    Console.WriteLine("Скачиваем : {0}" , url);
          client.DownloadString(url);            
    }           
     
    long elapsed = sw.ElapsedMilliseconds;
    Console.WriteLine("Затраченное время в миллисекундах: {0}",elapsed);
                sw.Stop();
  • Запустим программу. На экране отобразится результат выполнение алгоритма: (рис 10.6)
  • Далее, создадим аналогичный цикл, который бы скачивал содержание Web-страниц, но в параллельном режиме:
    Console.WriteLine("============================");
          sw.Restart();
          Parallel.ForEach(urls, url =>
          {
              WebClient client = new WebClient();
              Console.WriteLine("Скачиваем : " + url);
              client.DownloadString(url);
          });
          elapsed = sw.ElapsedMilliseconds;
          Console.WriteLine("Затраченное время в миллисекундах: {0}", elapsed);
          sw.Stop();            
    
    Console.ReadLine();
  • Запустим программу. В результате на экране отобразится следующее: (рис 10.7)

    Примечание. Цикл Parallel.Foreach, будет выполняться значительно быстрее т.к. методы, прописанные внутри тела цикла, будут выполняться в несколько потоков.

    Листинг кода программы:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Collections;
    using System.Net;
    using System.Threading.Tasks;
    namespace ParallelForeachApplication
    {
        class Program
        {
            static void Main(string[] args)
            {
         List<string> urls =  new List<string>() { 
    "http://intuit.ru",                                  
    "http://rbc.ru",                                  
    "http://ozon.ru",                                  
    "http://google.com",                                 
    "http://mail.ru",                                 
    "http://lenta.ru"                              
    };            
    System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();        
                    
    foreach (string url in urls)            
    {                
    WebClient client = new WebClient();                
    Console.WriteLine("Скачиваем : {0}" , url);
                    client.DownloadString(url);            
    }           
     
    long elapsed = sw.ElapsedMilliseconds;
    Console.WriteLine("Затраченное время в миллисекундах: {0}",elapsed);
                sw.Stop();
                Console.WriteLine("============================");
                sw.Restart();
                Parallel.ForEach(urls, url =>
                {
                    WebClient client = new WebClient();
                    Console.WriteLine("Скачиваем : " + url);
                    client.DownloadString(url);
                });
                elapsed = sw.ElapsedMilliseconds;
                Console.WriteLine("Затраченное время в миллисекундах: {0}", elapsed);
                sw.Stop();            
    Console.ReadLine();        
    }    
            }
        }
  • Вернуться к учебному плану