![]() |
|
|
|
|
#1
|
|||
|
|||
|
Доброго времени суток.
Попробовал написать многопоточную программу (до этого нужды не было в это лезть) и как говорится первый блин комом. Суть проблемы в следующем программа производит значительное число однотипных расчетов, по сути которые можно обсчитывать параллельно. С помощью класса TThread создается программой несколько потоков (число потоков определяется пользователь программы) каждый из которых берет на себя равную часть расчетов. Потоки формируются и отрабатывают правильно расчет (проверял) однако скорость осталась прежней, что и с одним потоком. В диспетчере задач показано, что программе присвоен один процесс и загрузка процессора всегда 25%, не зависимо от числа потоков. Что я не правильно понял? |
|
#2
|
||||
|
||||
|
Кусок кода сказал бы больше, чем 80% вашего сообщения
![]() |
|
#3
|
|||
|
|||
|
Цитата:
Код:
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
|
||||
|
||||
|
Код:
ther[it-1].start; Код:
ther[it-1].resume; P.S. А, ну и процедуры расчёта должны быть, как говорится, ThreadSafe - думаю, это объяснять не надо? P.P.S. Цитата:
![]() P.P.P.S. Ну и число потоков лучше рассчитывать из числа процессоров/ядер, а не из объёма работ. Последний раз редактировалось PhoeniX, 17.12.2013 в 20:45. |
|
#5
|
||||
|
||||
|
Небольшое дополнение.
Код:
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)Код:
ther[it-1].kss:=(it-1)*(kg mod itc); ther[it-1].ke:=(it)*(kg mod itc) - 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 поток по завершении самоуничтожается, а ты после этого его флаги читаешь. Не гут. Цитата:
Последний раз редактировалось Bargest, 17.12.2013 в 21:14. |
|
#6
|
|||
|
|||
|
Вы правы Ваш код изящней!!!
Цитата:
Но главный вопрос при этом коде ни скорость счета ни загрузка процессора не зависит от числа потоков. Процессор всегда загружен на 25% (похоже на одно ядро)!!! Почему?????? |
|
#7
|
||||
|
||||
|
Цитата:
Цитата:
Цитата:
ЗЫЖ черт, совсем забыл, что в делфе нет do-while... Надо поменять на repeat-until и условие поставить обратное.Последний раз редактировалось Bargest, 17.12.2013 в 22:32. |
| Этот пользователь сказал Спасибо Bargest за это полезное сообщение: | ||
mustimur (18.12.2013)
| ||
|
#8
|
|||
|
|||
|
Цитата:
Шутку оценил ![]() Код:
ther.resume |