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

Delphi Sources



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

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 16.05.2015, 10:48
nikola129 nikola129 вне форума
Прохожий
 
Регистрация: 16.05.2015
Сообщения: 4
Версия Delphi: Delphi2006
Репутация: 10
По умолчанию Потоки в готовой программе

Есть готовая программа, в которой производятся расчеты по вложенным циклам.
На 4-х ядерном процессоре загрузка не превышает 25%.
Итак, вызываются несколько функций, примерно так:
a1:=f1(a,b,c);
a2:=f2(x,y,z);
.............
an:=fn(m,n,l);
Затем результаты объединяются. Можно ли направить эти функции в разные потоки?
И как? Заранее благодарен,
Ответить с цитированием
  #2  
Старый 16.05.2015, 17:21
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,723
Репутация: 52347
По умолчанию

И вы думаете разные потоки будут крутится на разных ядрах? А вот и нетушки.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #3  
Старый 16.05.2015, 17:24
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,723
Репутация: 52347
По умолчанию

Если вы хотите получить реальный прирост производительности при расчетах, то нагружать надо графический процессор. Там прирост будет в разы.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #4  
Старый 16.05.2015, 18:26
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Цитата:
И вы думаете разные потоки будут крутится на разных ядрах? А вот и нетушки.
Таки да. В любой нормальной ОС при наличии свободных ядер (а если активно занимает процессор только эта программа, то таковые имеются) потоки будут запущены на разных ядрах. Не далее, как неделю назад, запускал подсчет инфы от большого числа файлов: имел 24 ядра, запустил в 24 потока. Стало примерно в 20 раз быстрее. И загрузка процессора стала не 4%, а все 100%.

А потому можно сделать функцию, которая принимает агрументы и адерс функции вычисления (ведь все функции одинаковые по количеству и типу параметров), вызывает и сохраняет результат. После чего запустить много потоков (по числу ядер), передав соответствующие функции подсчета и аргументы.

А граф процессор, конечно, можно, но это уже не за 10 минут делается, это надо очень много курить все эти OpenMP и прочую жесть.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 16.05.2015 в 22:05.
Ответить с цитированием
  #5  
Старый 16.05.2015, 20:10
nikola129 nikola129 вне форума
Прохожий
 
Регистрация: 16.05.2015
Сообщения: 4
Версия Delphi: Delphi2006
Репутация: 10
По умолчанию

Если можно, поподробнее.
Как к потоку привязать функцию?
Ответить с цитированием
  #6  
Старый 16.05.2015, 21:27
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Направление я дал. А переписывать в 1001-й раз учебник по потокам не собираюсь. По передачам функций тоже. Можно же хоть немного самому что-то поделать?
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 16.05.2015 в 22:03.
Ответить с цитированием
  #7  
Старый 17.05.2015, 02:37
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Цитата:
Сообщение от Bargest
... потоки будут запущены на разных ядрах...
Насколько мне известно (может что-то изменилось), но TThread не делит потоки на разные ядра. Увы. Автору читать про SetThreadAffinityMask.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #8  
Старый 17.05.2015, 07:18
nikola129 nikola129 вне форума
Прохожий
 
Регистрация: 16.05.2015
Сообщения: 4
Версия Delphi: Delphi2006
Репутация: 10
По умолчанию

С потоками я дела не имел, но интернет по подобным ссылкам просмотрел.
Пробовал это:
Код:
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.
Грузит все четыре ядра. Нашел интересное: http://www.delphikingdom.ru/asp/view...catalogid=1355
но это не работает, как хотелось.
Ответить с цитированием
  #9  
Старый 17.05.2015, 10:58
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,723
Репутация: 52347
По умолчанию

Только в методе Execute добавьте Sleep(1) хотя-бы на каждом проходе while.
Ваш пример загрузит процессор, распределив нагрузку между ядрами, но при этом каждый поток будет обрабатываться не в отдельном ядре, а нагрузка от всех этих потоков будет распределена между ядрами. Может даже так случится, что 4 потока будут работать только на 3 ядрах, совершенно не используя остальные.

ПС: Не уверен, т.к. не пользовался, но с помощью функции SetThreadAffinityMask можно реально заставить конкретный поток исполнятся на конкретном ядре.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.

Последний раз редактировалось Страдалецъ, 17.05.2015 в 11:04.
Ответить с цитированием
  #10  
Старый 17.05.2015, 13:10
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Цитата:
TThread не делит потоки на разные ядра. Увы. Автору читать про SetThreadAffinityMask.
Конечно, нет однозначного соответствия. Именно поэтому распараллеливание на 24 потока дало прирост не в 24 раза, а немного меньше. Более того, если запустить много нагружающих процессор приложений, то все потоки вероятнее всего будут выполняться по очереди на одном и том же ядре, т.к. другие будут заняты. Но это редкая ситуация.
А потоки на разные ядра распределяет не TThread и делфовый рантайм, а сама система. Конструктор TThread вызывает BeginThread, а тот есть обертка над WinAPI-шным CreateThread, поэтому делфовый поток есть обычный системный поток. Диспетчер при освобождении любого ядра проверяет, нет ли еще каких потоков в ожидании, и если есть, то запускает. Скорее всего, потоки будут циклически "кочевать" между ядрами, но тем не менее в любой момент времени будут заняты все доступные ресурсы процессора, минус только в том, что часть ресурсов будет постоянно заниматься переключением, но время этой операции по сравнению с квантом времени потока - ничто. Поэтому хоть формально и нет однозначного соответствия ядро->поток, это не сильно вредит производительности.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 17.05.2015 в 13:23.
Ответить с цитированием
  #11  
Старый 17.05.2015, 15:07
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 577
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от Bargest
Более того, если запустить много нагружающих процессор приложений, то все потоки вероятнее всего будут выполняться по очереди на одном и том же ядре, т.к. другие будут заняты.
Все потоки должны распределяться вперемешку. Раз в единицей исполнения является поток, Windows должно быть начхать, к какому процессу он относится.

А что у автора темы потоки по ядрам не параллелятся -- так это он наверняка с синхронизацией намудрил, и они тупо по очереди работают.
__________________
Не стоит путать форумы с богадельнями. © Bargest
Ответить с цитированием
  #12  
Старый 17.05.2015, 15:48
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Цитата:
Все потоки должны распределяться вперемешку. Раз в единицей исполнения является поток, Windows должно быть начхать, к какому процессу он относится.
Надеюсь, что не начхать. Потому что с т.з. производительности лучше потоки одного процесса запускать всегда на одном и том же ядре, а не скакать между ними, если все равно занимать все ресурсы. Реже cache miss будет, по идеи. Но может и правда скакать будут.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
  #13  
Старый 18.05.2015, 10:23
nikola129 nikola129 вне форума
Прохожий
 
Регистрация: 16.05.2015
Сообщения: 4
Версия Delphi: Delphi2006
Репутация: 10
По умолчанию

А все-таки, как к потоку привязать функцию?
Ответить с цитированием
Ответ


Delphi Sources

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

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

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

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


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


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

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