Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 |

 

  Вопрос: Ускорение цикла за счет количества потоков. Добавлено: 26.11.09 14:57  

Автор вопроса:  SHS
Допустим есть цикл:


For i=1 to 1000
   Console.Writeline(i)
Next


Как этот цикл выполнить в несколько потоков?
Чтоб количество потоков мог задать пользователь.

Тоесть если выбрано 10 потоков, то
Первый поток делает суммирование от 1 до 100
Второй поток от 100 до 200
.....
И тд и тп....
И одновременно.

Одним словом надо этот цикл оптимизировать по скорости за счет количества потоков.
Подойдет любой вариант, будь то BackgroundWorker или System.Threading.

Ато я уже голову сломал, нигде решения найти не могу...

Ответить

  Ответы Всего ответов: 9  

Номер ответа: 1
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #1 Добавлено: 26.11.09 20:55
надо этот цикл оптимизировать по скорости за счет количества потоков.


  1.  
  2.     class Program
  3.     {
  4.         static int step = 100;
  5.         static void Main(string[] args)
  6.         {
  7.             int counter = 0;
  8.             do
  9.             {
  10.                 Thread t = new Thread(DoWork) { IsBackground = true };
  11.                 t.Start(counter);
  12.                 counter += step;
  13.             } while (counter < 1000);
  14.  
  15.             /* wait */
  16.             Console.ReadLine();
  17.         }
  18.  
  19.         private static void DoWork(object state)
  20.         {
  21.             int result = 0;
  22.             int counter = (int)state;
  23.             int stop = (int)state + step;
  24.             do
  25.             {
  26.                 result += counter;
  27.                 counter++;
  28.             } while (counter < stop);
  29.  
  30.             Console.WriteLine("Start - {0}\tResult: {1}", (int)state, result);
  31.         }
  32.     }
  33.  



Но должен предупредить что зачастую потоки не дают ощутимого преимущества в скорости.. Более эффективнее оптимизировать сам код..

Ответить

Номер ответа: 2
Автор ответа:
 VβÐUηìt



Вопросов: 246
Ответов: 3333
 Web-сайт: смекаешь.рф
 Профиль | | #2
Добавлено: 26.11.09 21:12
Ну блин. Если на кварде запускать не в один поток, а в четыре, то прирост весьма весьма ощутимый)) И вообще, не то что бы так или этак, а количество потоков должно равняться количеству ядер процессора, ибо тогда достигается наивысшая производительность. Измерено ручками. Не зря же 3Ds max, Maya и др. при рендеринге создают ровно столько потоков, сколько CPU, не больше, не меньше.

Ответить

Номер ответа: 3
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #3 Добавлено: 26.11.09 21:22
количество потоков должно равняться количеству ядер процессора,

глупости... потоки никак не связаны с процессорами... если проц посчитает нужным, то все твои потоки будут работать на 1 ядре.. А вот новый FW позволяет распаралеллить вычисления именно по ядрам.. вот там да, реальный прирост в скорости.

Ответить

Номер ответа: 4
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #4
Добавлено: 26.11.09 21:39
количество потоков должно равняться количеству ядер процессора

Это в том случае, если задача сама хорошо параллелится. На многих задачах уже два потока синхронизациями сожрут больше половины производительности и будут работать медленнее одного. Наиболее удобно в дотнете параллелизация представлена в F#, конструкция async. В нормальном языке (тм) следует использовать промышленный стандарт OpenMP.

Ответить

Номер ответа: 5
Автор ответа:
 SHS



Вопросов: 2
Ответов: 5
 Профиль | | #5 Добавлено: 26.11.09 21:48
Спасибо за ответ.
Перевел в код VB, который собственно мне и нужен:

  1.  
  2. Module Module1
  3.     Sub Main()
  4.         Dim step1 As Integer = 100
  5.         Dim counter As Integer = 0
  6.         Do While (counter < 1000)
  7.             Dim t As Thread = New Thread(AddressOf DoWork)
  8.             t.IsBackground = True
  9.             t.Start(counter)
  10.             counter += step1
  11.         Loop
  12.         Console.ReadLine()
  13.     End Sub
  14.  
  15.     Private Sub DoWork(ByVal state As Object)
  16.  
  17.         Dim result As Integer = 0
  18.         Dim counter As Integer = Val(state)
  19.         Dim stop1 As Integer = Val(state) + 1
  20.         Do While (counter < stop1)
  21.             result += counter
  22.             counter += 1
  23.         Loop
  24.         Console.WriteLine("Start - {0}   Result: {1}", Val(state), result)
  25.     End Sub
  26.  
  27. End Module



Output:
Start - 0 Result: 0
Start - 100 Result: 100
Start - 200 Result: 200
Start - 300 Result: 300
Start - 400 Result: 400
Start - 600 Result: 600
Start - 500 Result: 500
Start - 800 Result: 800
Start - 700 Result: 700
Start - 900 Result: 900

Все верно получается?

Ответить

Номер ответа: 6
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #6 Добавлено: 26.11.09 22:38
нифига не верно..

http://clip2net.com/clip/m25397/1259264258-clip-31kb.jpg

Ответить

Номер ответа: 7
Автор ответа:
 SHS



Вопросов: 2
Ответов: 5
 Профиль | | #7 Добавлено: 27.11.09 07:06
У меня нестыковка идет с переменной step в процедуре dowork. А именно (int)state + step. Требует объявления.

Ответить

Номер ответа: 8
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #8 Добавлено: 27.11.09 07:54
ну так правильно.. у меня эта переменая объявлена на уровне класса а у тебя на уровне процедуры.. разумеется у тебя она не попадает в зону видимости..

Ответить

Номер ответа: 9
Автор ответа:
 SHS



Вопросов: 2
Ответов: 5
 Профиль | | #9 Добавлено: 27.11.09 13:21
Спасибо за помощь.
Работает.

  1.  
  2.  
  3. Imports System.Threading
  4.  
  5. Module Module1
  6.     Private step1 As Integer = 100
  7.     Sub Main()
  8.         Dim counter As Integer = 0
  9.         Do While (counter < 1000)
  10.             Dim t As Thread = New Thread(AddressOf DoWork)
  11.             t.IsBackground = True
  12.             t.Start(counter)
  13.             counter += step1
  14.         Loop
  15.         Console.ReadLine()
  16.     End Sub
  17.  
  18.     Private Sub DoWork(ByVal state As Object)
  19.  
  20.         Dim result As Integer = 0
  21.         Dim counter As Integer = Val(state)
  22.         Dim stop1 As Integer = Val(state) + step1
  23.         Do While (counter < stop1)
  24.             result += counter
  25.             counter += 1
  26.         Loop
  27.         Console.WriteLine("Start - {0}   Result: {1}", Val(state), result)
  28.     End Sub
  29.  
  30. End Module
  31.  

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам