![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
![]() Есть готовая программа, в которой производятся расчеты по вложенным циклам.
На 4-х ядерном процессоре загрузка не превышает 25%. Итак, вызываются несколько функций, примерно так: a1:=f1(a,b,c); a2:=f2(x,y,z); ............. an:=fn(m,n,l); Затем результаты объединяются. Можно ли направить эти функции в разные потоки? И как? Заранее благодарен, |
#2
|
||||
|
||||
![]() И вы думаете разные потоки будут крутится на разных ядрах? А вот и нетушки.
Жизнь такова какова она есть и больше никакова. Помогаю за спасибо. |
#3
|
||||
|
||||
![]() Если вы хотите получить реальный прирост производительности при расчетах, то нагружать надо графический процессор. Там прирост будет в разы.
Жизнь такова какова она есть и больше никакова. Помогаю за спасибо. |
#4
|
||||
|
||||
![]() Цитата:
А потому можно сделать функцию, которая принимает агрументы и адерс функции вычисления (ведь все функции одинаковые по количеству и типу параметров), вызывает и сохраняет результат. После чего запустить много потоков (по числу ядер), передав соответствующие функции подсчета и аргументы. А граф процессор, конечно, можно, но это уже не за 10 минут делается, это надо очень много курить все эти OpenMP и прочую жесть. jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось Bargest, 16.05.2015 в 22:05. |
#5
|
|||
|
|||
![]() Если можно, поподробнее.
Как к потоку привязать функцию? |
#6
|
||||
|
||||
![]() Направление я дал. А переписывать в 1001-й раз учебник по потокам не собираюсь. По передачам функций тоже. Можно же хоть немного самому что-то поделать?
jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось Bargest, 16.05.2015 в 22:03. |
#7
|
||||
|
||||
![]() Цитата:
Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |
#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, поэтому делфовый поток есть обычный системный поток. Диспетчер при освобождении любого ядра проверяет, нет ли еще каких потоков в ожидании, и если есть, то запускает. Скорее всего, потоки будут циклически "кочевать" между ядрами, но тем не менее в любой момент времени будут заняты все доступные ресурсы процессора, минус только в том, что часть ресурсов будет постоянно заниматься переключением, но время этой операции по сравнению с квантом времени потока - ничто. Поэтому хоть формально и нет однозначного соответствия ядро->поток, это не сильно вредит производительности. jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось Bargest, 17.05.2015 в 13:23. |
#11
|
||||
|
||||
![]() Цитата:
А что у автора темы потоки по ядрам не параллелятся -- так это он наверняка с синхронизацией намудрил, и они тупо по очереди работают. Не стоит путать форумы с богадельнями. © Bargest |
#12
|
||||
|
||||
![]() Цитата:
jmp $ ; Happy End! The Cake Is A Lie. |
#13
|
|||
|
|||
![]() А все-таки, как к потоку привязать функцию?
|