Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > ОС и железо
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 17.12.2013, 19:44
mustimur mustimur вне форума
Прохожий
 
Регистрация: 20.11.2013
Сообщения: 17
Версия Delphi: Delphi xe4
Репутация: 10
По умолчанию Многопоточность

Доброго времени суток.

Попробовал написать многопоточную программу (до этого нужды не было в это лезть) и как говорится первый блин комом.
Суть проблемы в следующем программа производит значительное число однотипных расчетов, по сути которые можно обсчитывать параллельно.
С помощью класса TThread создается программой несколько потоков (число потоков определяется пользователь программы) каждый из которых берет на себя равную часть расчетов. Потоки формируются и отрабатывают правильно расчет (проверял) однако скорость осталась прежней, что и с одним потоком. В диспетчере задач показано, что программе присвоен один процесс и загрузка процессора всегда 25%, не зависимо от числа потоков.
Что я не правильно понял?
Ответить с цитированием
  #2  
Старый 17.12.2013, 20:17
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

Кусок кода сказал бы больше, чем 80% вашего сообщения
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
  #3  
Старый 17.12.2013, 20:32
mustimur mustimur вне форума
Прохожий
 
Регистрация: 20.11.2013
Сообщения: 17
Версия Delphi: Delphi xe4
Репутация: 10
По умолчанию Код специфичный)))

Цитата:
Сообщение от PhoeniX
Кусок кода сказал бы больше, чем 80% вашего сообщения
Я не думаю что легче будет, но код вот:
Код:
itc:=sedt.Value;// Определяет число параллельный потоков
setlength(ther,itc); 
for it := 1 to itc do
  begin
  ther[it-1]:= Rasch.Create(true); //Rasch - мой класс TThread
  ther[it-1].FreeOnTerminate := true;
  if it =1 then ther[it-1].kss:=0 else ther[it-1].kss:=(it-1)*(kg mod itc)+1;// определяет с какого элемента считать начать текущему потоку
  if it=itc then ther[it-1].ke:=kg else ther[it-1].ke:=(it)*(kg mod itc); // определяет каким элементом закончить счет текущему потоку
  ther[it-1].proc:=rasc1; // определяет процедуру для расчета
  ther[it-1].start;
end;
  enp:=false;
  while (enp=false) do //Ожидание окончание всех потоков
  begin
  enp:=ther[0].Finished;
  if itc>1 then for it := 2 to itc do enp:=(enp and ther[it-1].Finished);
  end;

Чтобы было понятнее приложу код класса Rasch
Код:
unit Rasc;

interface

uses
  System.Classes;

type
  ProcRasc = procedure(kstr, kend:integer);
  Rasch = class(TThread)
  private
    { Private declarations }
  public
  
  proc: ProcRasc;
  kss,ke: integer;

  protected
    procedure Execute; override;
  end;


implementation


{ Rasch }

procedure Rasch.Execute;
begin
  proc(kss,ke);
end;

end.

Последний раз редактировалось mustimur, 17.12.2013 в 20:38.
Ответить с цитированием
  #4  
Старый 17.12.2013, 20:39
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

Код:
ther[it-1].start;
Попробуй заменить на
Код:
ther[it-1].resume;
В остальном всё должно работать...

P.S. А, ну и процедуры расчёта должны быть, как говорится, ThreadSafe - думаю, это объяснять не надо?
P.P.S.
Цитата:
Сообщение от mustimur
Я не думаю что легче будет
Мы тут экземпляры класса TProgrammer, и у нас метод Understand заточен под тип сообщений TCode
P.P.P.S. Ну и число потоков лучше рассчитывать из числа процессоров/ядер, а не из объёма работ.
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj

Последний раз редактировалось PhoeniX, 17.12.2013 в 20:45.
Ответить с цитированием
  #5  
Старый 17.12.2013, 21:03
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Небольшое дополнение.
Код:
while (enp=false) do //Ожидание окончание всех потоков
  begin
  enp:=ther[0].Finished;
  if itc>1 then for it := 2 to itc do enp:=(enp and ther[it-1].Finished);
  end;
Было бы логичней
Код:
do
  enp = true;
  for it := 0 to itc - 1 do
    enp := enp and ther[it].Finished;
while (enp = false)
Ну и IF-ы в составлении потоков можно и убрать:
Код:
ther[it-1].kss:=(it-1)*(kg mod itc);
ther[it-1].ke:=(it)*(kg mod itc) - 1;
После чего этот цикл тоже перевести на 0 to itc-1 и повысить читаемость, убрав все -1 и добавив в одном месте +1.
Код:
for it := 0 to itc-1 do
  begin
  ther[it]:= Rasch.Create(true);
  ther[it].FreeOnTerminate := true;
  ther[it].kss:=it*(kg mod itc);
  ther[it].ke:=(it + 1)*(kg mod itc) - 1;
  ther[it].proc:=rasc1;
  ther[it].start;
end;
Проще читается как-то.
ЗЫЖ если я правильно помню, при выставленном FreeOnTerminate поток по завершении самоуничтожается, а ты после этого его флаги читаешь. Не гут.
Цитата:
Сообщение от Спеки Embarcadero
Warning: When FreeOnTerminate is true, the Execute method may run and then free the thread before your application can execute the next line of code. Thus, you should not call any methods of the thread object when FreeOnTerminate is true unless you create the thread in a suspended state. FreeOnTerminate is best left for threads that simply perform a task and then naturally terminate. If you want to communicate with the thread or otherwise interact with it, including telling it when to terminate, FreeOnTerminate should never be used.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 17.12.2013 в 21:14.
Ответить с цитированием
  #6  
Старый 17.12.2013, 22:01
mustimur mustimur вне форума
Прохожий
 
Регистрация: 20.11.2013
Сообщения: 17
Версия Delphi: Delphi xe4
Репутация: 10
Вопрос

Вы правы Ваш код изящней!!!

Цитата:
Сообщение от Bargest


Проще читается как-то.
ЗЫЖ если я правильно помню, при выставленном FreeOnTerminate поток по завершении самоуничтожается, а ты после этого его флаги читаешь. Не гут.
так я надеюсь на его уничтожение по завершении расчетов и жду этого, когда все потоки уничтожатся, чтобы продолжить... А что не так?

Но главный вопрос при этом коде ни скорость счета ни загрузка процессора не зависит от числа потоков. Процессор всегда загружен на 25% (похоже на одно ядро)!!! Почему??????
Ответить с цитированием
  #7  
Старый 17.12.2013, 22:20
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Цитата:
Сообщение от mustimur
Простите комп повис как удалить повторы?
Никак. Попроси модеров (Admin, M.A.D.M.A.N, lmikle). Пока отредактируй и измени текст на < удалено > (т.к. минимум 10 символов).
Цитата:
А что не так?
Поток завершился, объект удалился, а потом ты обращаешься к его полю Finished, т.е. к полю несуществующего объекта. Работать скорее всего будет в большинстве случаев, но только благодаря тому, что память не зануляется при удалении.
Цитата:
(похоже на одно ядро)!!! Почему??????
Приложи еще код расчетов.
ЗЫЖ черт, совсем забыл, что в делфе нет do-while... Надо поменять на repeat-until и условие поставить обратное.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 17.12.2013 в 22:32.
Ответить с цитированием
Этот пользователь сказал Спасибо Bargest за это полезное сообщение:
mustimur (18.12.2013)
  #8  
Старый 17.12.2013, 21:50
mustimur mustimur вне форума
Прохожий
 
Регистрация: 20.11.2013
Сообщения: 17
Версия Delphi: Delphi xe4
Репутация: 10
По умолчанию

Цитата:
Сообщение от PhoeniX

Мы тут экземпляры класса TProgrammer, и у нас метод Understand заточен под тип сообщений TCode .

Шутку оценил
Код:
ther.resume
пробовал результаты теже....
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 05:32.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025