![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
Есть готовая программа, в которой производятся расчеты по вложенным циклам.
На 4-х ядерном процессоре загрузка не превышает 25%. Итак, вызываются несколько функций, примерно так: a1:=f1(a,b,c); a2:=f2(x,y,z); ............. an:=fn(m,n,l); Затем результаты объединяются. Можно ли направить эти функции в разные потоки? И как? Заранее благодарен, |
|
#2
|
||||
|
||||
|
И вы думаете разные потоки будут крутится на разных ядрах? А вот и нетушки.
|
|
#3
|
||||
|
||||
|
Если вы хотите получить реальный прирост производительности при расчетах, то нагружать надо графический процессор. Там прирост будет в разы.
|
|
#4
|
||||
|
||||
|
Цитата:
А потому можно сделать функцию, которая принимает агрументы и адерс функции вычисления (ведь все функции одинаковые по количеству и типу параметров), вызывает и сохраняет результат. После чего запустить много потоков (по числу ядер), передав соответствующие функции подсчета и аргументы. А граф процессор, конечно, можно, но это уже не за 10 минут делается, это надо очень много курить все эти OpenMP и прочую жесть. Последний раз редактировалось Bargest, 16.05.2015 в 22:05. |
|
#5
|
|||
|
|||
|
Если можно, поподробнее.
Как к потоку привязать функцию? |
|
#6
|
||||
|
||||
|
Направление я дал. А переписывать в 1001-й раз учебник по потокам не собираюсь. По передачам функций тоже. Можно же хоть немного самому что-то поделать?
Последний раз редактировалось Bargest, 16.05.2015 в 22:03. |
|
#7
|
||||
|
||||
|
Цитата:
|
|
#8
|
|||
|
|||
|
С потоками я дела не имел, но интернет по подобным ссылкам просмотрел.
Пробовал это: Код:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TNewThread = class(TThread)
private
protected
procedure Execute; override;
public
{ Public declarations }
end;
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
const n=3;
var
Form1: TForm1;
thread: array[0..n] of TNewThread;
implementation
{$R *.dfm}
procedure TNewThread.Execute;
var i: byte;
begin
for I := 0 to n do
while true do {ничего не делаем}
if thread[i].Terminated then
break;
end;
procedure TForm1.Button1Click(Sender: TObject);
var i: Integer;
begin
for i := 0 to n do
begin
thread[i]:= TNewThread.Create(true);
thread[i].FreeOnTerminate:= true;
thread[i].Priority:= tpLower;
thread[i].Resume;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var i: Integer;
begin
for i := 0 to n do
if not thread[i].Terminated then
thread[i].Terminate;
ShowMessage('Завершение работы потоков');
end;
end.но это не работает, как хотелось. |
|
#9
|
||||
|
||||
|
Только в методе Execute добавьте Sleep(1) хотя-бы на каждом проходе while.
Ваш пример загрузит процессор, распределив нагрузку между ядрами, но при этом каждый поток будет обрабатываться не в отдельном ядре, а нагрузка от всех этих потоков будет распределена между ядрами. Может даже так случится, что 4 потока будут работать только на 3 ядрах, совершенно не используя остальные. ПС: Не уверен, т.к. не пользовался, но с помощью функции SetThreadAffinityMask можно реально заставить конкретный поток исполнятся на конкретном ядре. Последний раз редактировалось Страдалецъ, 17.05.2015 в 11:04. |
|
#10
|
||||
|
||||
|
Цитата:
А потоки на разные ядра распределяет не TThread и делфовый рантайм, а сама система. Конструктор TThread вызывает BeginThread, а тот есть обертка над WinAPI-шным CreateThread, поэтому делфовый поток есть обычный системный поток. Диспетчер при освобождении любого ядра проверяет, нет ли еще каких потоков в ожидании, и если есть, то запускает. Скорее всего, потоки будут циклически "кочевать" между ядрами, но тем не менее в любой момент времени будут заняты все доступные ресурсы процессора, минус только в том, что часть ресурсов будет постоянно заниматься переключением, но время этой операции по сравнению с квантом времени потока - ничто. Поэтому хоть формально и нет однозначного соответствия ядро->поток, это не сильно вредит производительности. Последний раз редактировалось Bargest, 17.05.2015 в 13:23. |
|
#11
|
||||
|
||||
|
Цитата:
А что у автора темы потоки по ядрам не параллелятся -- так это он наверняка с синхронизацией намудрил, и они тупо по очереди работают. |
|
#12
|
||||
|
||||
|
Цитата:
|
|
#13
|
|||
|
|||
|
А все-таки, как к потоку привязать функцию?
|