Модераторы: Snowy, MetalFan, bems, Poseidon

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Распараллеливание потока 
:(
    Опции темы
Демо
Дата 24.7.2007, 10:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 7
Всего: 50



Цитата(W4FhLF @  19.7.2007,  07:32 Найти цитируемый пост)
Распараллеливание в данном случае прироста к скорости не даст. 


Даёт.

eXa

для решения твоей задачи возможны несколько подходов.

Пару я опишу. После реализации протестируешь, который из них оптимальнее (лень оценивать сейчас).

1.
- Для каждого потока выделяется диапазон строк из TStringList;
- строки при создании потока копируются для обработки, на время копирования TStringList блокируется для доступа из других потоков средствами синхронизации
- каждый поток обрабатывает свой список строк, затеп копирует обратно, на время копирования TStringList блокируется для доступа из других потоков средствами синхронизации

2. 
- Каждый поток обрабатывает строки из диапазона ПОСТРОЧНО. При этом исходный список блокируется на время копирования строки в поток, а затем обратно.

Вот примерный код для первого метода:

Код

unit ufMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, SyncObjs;

type

  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

    TFirstThread=class(TThread)
    private
    FList: TStringlist;
    FMainList: TStringList;
    FCS: TCriticalSection;
    FB, FE: Integer;
  public
    constructor Create(List: TStrings; BIndex,EIndex: integer; aCS: TCriticalSection);
    destructor Destroy; override;
  protected
    procedure Execute; override;
    end;

var
  Form1: TForm1;
  CS: TCriticalSection;
implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
    CS := TCriticalSection.Create;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
    Memo1.Lines.LoadFromFile('c:\test.txt');
  TFirstThread.Create(Memo1.Lines,0,(Memo1.Lines.Count div 2),CS);
  TFirstThread.Create(Memo1.Lines,(Memo1.Lines.Count div 2)+1,Memo1.Lines.Count-1,CS);
end;

{ TFirstThread }

constructor TFirstThread.Create(List: TStrings; BIndex, EIndex: integer; aCS: TCriticalSection);
var
    i: integer;
begin
    inherited Create(True);
    FreeOnTerminate := True;
  FList := TStringList.Create;
  FMainList := TStringList(List);
  FCS := aCS;
  FB :=BIndex;
  FE := EIndex;
    FCS.Enter;
  try
    try
        for i := FB to FE do FList.Add(List[i]);
    except
     //Îáðàáîòêà îøèáêè
      Terminate;
    end;
  finally
    FCS.Leave;
  end;
  Resume;
end;

destructor TFirstThread.Destroy;
begin
    FList.Free;
  inherited;
end;

procedure TFirstThread.Execute;
var
    i: Integer;
begin
    for i := 0 to FList.Count-1 do
  begin
    //îáðàáîòêà ñòðîêè
    if Terminated then Exit;
  end;

    FCS.Enter;
  try
    try
        for i := 0 to FList.Count-1 do FMainList[i+FB] := FList[i];
    except
            //îáðàáîòêà îøèáêè
    end;
  finally
    FCS.Leave;
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    CS.Free;
end;

end.




--------------------
    
PM MAIL ICQ Skype   Вверх
dumb
Дата 24.7.2007, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 3
Всего: 158



Цитата(Демо @  24.7.2007,  10:13 Найти цитируемый пост)
Цитата(W4FhLF @  19.7.2007,  07:32 Найти цитируемый пост)
Распараллеливание в данном случае прироста к скорости не даст.

Даёт.

эк безапелляционно. распараллеливание даст прирост только в случае небольшого файла и очень ресурсоемкой обработки каждой строки. в "нашем" же случае, я больше чем уверен, что обработка простейшая, а тормоза получаются из-за загрузки довольно объемного файла в стринг-лист.
так что гораздо быстрее получится, если просто читать файл построчно...
PM MAIL   Вверх
Демо
Дата 24.7.2007, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 7
Всего: 50



Цитата(dumb @  24.7.2007,  13:25 Найти цитируемый пост)
эк безапелляционно. распараллеливание даст прирост только в случае небольшого файла и очень ресурсоемкой обработки каждой строки. в "нашем" же случае, я больше чем уверен, что обработка простейшая, а тормоза получаются из-за загрузки довольно объемного файла в стринг-лист.так что гораздо быстрее получится, если просто читать файл построчно...


безапелляционно, потому что знание - сила.

Ты упустил одну маленькую деталь - система может быть многопроцессорной.


--------------------
    
PM MAIL ICQ Skype   Вверх
dumb
Дата 24.7.2007, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 3
Всего: 158



Цитата(Демо @  24.7.2007,  14:34 Найти цитируемый пост)
Ты упустил одну маленькую деталь - система может быть многопроцессорной.

не упустил. при простой обработке и большом объеме файла основные тормоза - операция чтения с диска: тут кол-во процессоров никакой роли не сыграет. а вот расходы на загрузку в стринг-грид(в основном) и создание тредов - очень даже.
PM MAIL   Вверх
eXa
Дата 24.7.2007, 15:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 133
Регистрация: 1.12.2006

Репутация: нет
Всего: нет



Спасиб +100 за помощь, поразбираюсь когда будет время, а в сабже я привёл только пример для примера потоков  smile  А конечной целью является ускорение отсылаемых данных на сервер, которые берутся из txt файла построчно и задаваемое кол-во потоков...
PM MAIL   Вверх
Демо
Дата 24.7.2007, 15:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 7
Всего: 50



Цитата(dumb @  24.7.2007,  15:05 Найти цитируемый пост)
не упустил. при простой обработке и большом объеме файла основные тормоза - операция чтения с диска: тут кол-во процессоров никакой роли не сыграет. а вот расходы на загрузку в стринг-грид(в основном) и создание тредов - очень даже.


Размер файла не имеет значения. Пусть это 10Кб-файл или файл размером 10Гб.
Важна реализация.

Добавлено @ 15:24
Цитата(dumb @  24.7.2007,  15:05 Найти цитируемый пост)
большом объеме файла основные тормоза - операция чтения с диска


Опять же. Диск диску рознь.
При кэше размером в несколько мегабайт и быстрых современных дисках со скоростью в десятки Мб/сек скорость обработки данных очень даже будет иметь значение. 

Это сообщение отредактировал(а) Демо - 24.7.2007, 15:25


--------------------
    
PM MAIL ICQ Skype   Вверх
eXa
Дата 26.7.2007, 08:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 133
Регистрация: 1.12.2006

Репутация: нет
Всего: нет



А вот что делать, если  на форме есть TEdit который используеться в потоки, если TEdit находится в class(TForm) то поток его не видит Undeclared identifier: 'Edit1' а в  class(TThread)  тоже не поместишь...
PM MAIL   Вверх
Демо
Дата 26.7.2007, 08:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 7
Всего: 50



eXa

1. Для использования VCL из отдельного потока в основном необходимо применять метод Synchronize;
2. При создании потока в конструктор можно передать ссылку на твой TEdit и использовать ее;

Код

TMyThread=class(TThread)
private
...
   FEdit: TEdit;

constructor TMyThread. Create(Ed: TEdit);
begin
   FEdit := Ed;


А дальше используешь просто как FEdit.Text, например.


--------------------
    
PM MAIL ICQ Skype   Вверх
aktuba
Дата 26.7.2007, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


Профиль
Группа: Завсегдатай
Сообщений: 1915
Регистрация: 24.4.2006
Где: Планета Земля

Репутация: 7
Всего: 38



Цитата

А дальше используешь просто как FEdit.Text, например. 


Ай-ай!!! Это что-же, правила работы с потоками не для всех пишуться???? А если ты будешь этот эдит будет использоваться в нескольких потоках???? В корне неверный совет!!!


--------------------
user posted image
PM MAIL WWW Skype   Вверх
Демо
Дата 26.7.2007, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 7
Всего: 50



Цитата(aktuba @  26.7.2007,  16:14 Найти цитируемый пост)
Ай-ай!!! Это что-же, правила работы с потоками не для всех пишуться???? А если ты будешь этот эдит будет использоваться в нескольких потоках???? В корне неверный совет!!!


См. предыдущий пост.
Читай внимательнее, пожалуйста, прежде чем замечания делать.


--------------------
    
PM MAIL ICQ Skype   Вверх
W4FhLF
Дата 26.7.2007, 16:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 1
Всего: 121



В случае, когда в системе один процессор/ядро оптимальное число потоков, для задачи, где НЕТ БЛОКИРУЮЩИХ ОПЕРАЦИЙ,  1 штука. Увеличение потоков даст прирост в случае, если в системе параллельно активно работают ещё несколько потоков(с таким же приоритетом). Но в этом случае будет лучше повысить потоку приоритет, нежели распараллеливать задачу. 

PS Одному из участников форума я доказывал справедливость моих слов по ПМ, с примерами и теоретическим обоснованием, он тоже был удивлён. 


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
Alexeis
Дата 26.7.2007, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



Цитата(W4FhLF @  26.7.2007,  16:53 Найти цитируемый пост)
PS Одному из участников форума я доказывал справедливость моих слов по ПМ, с примерами и теоретическим обоснованием, он тоже был удивлён. 

  Обоснования в студию smile . Я думаю, что если вручную указать каждому потоку на каком проце выполняться то прирост будет обязательно.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
W4FhLF
Дата 26.7.2007, 17:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 1
Всего: 121



Alexeis, ещё раз перечитай моё сообщение. Обязательны 3 условия:
1. Одно ядро/процессор.
2. Отсутствие блокирующих операций.
3. Отсутствие активно расходующих процессорное время параллельных потоков других приложения, с тем же приоритетом(почти у любого из нас система работает в этом режиме практически постоянно).

Сейчас будут обоснования.

Добавлено @ 17:10
Код

var
  Form1: TForm1;
  ad,i,a:integer;
  ThID: array [0..1] of dword;
  by: byte;

function ThreadProc(): dword; stdcall;
begin
    asm
      push ecx
      mov ecx,$FFFFFFFF
      @f:
        inc ad
        xor byte ptr[by],$64
        add byte ptr[by],$46
        xor byte ptr[by],$54
        shl byte ptr[by],2
      loop @f
      pop ecx
    end;
    ExitThread(0);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
    ThID[0] :=CreateThread(nil,128*1024,@ThreadProc,nil,0,ThID[0]);
    a := GetTickCount();
    WaitForMultipleObjects(1, @ThID, FALSE, INFINITE);
    ShowMessage(IntToStr(GetTickCount() - a));
end;



Что делает процедура ThreadProc можешь не вникать, суть в том, что там написан цикл, на ассемблере, с числом иттераций FFFFFFFF(4294967295). Наилучшее время выполнения: 56.766 сек. 

Далее запускаю такой пример:

Код

var
  Form1: TForm1;
  ad,i,a:integer;
  ThID: array [0..1] of dword;
  by: byte;

implementation

{$R *.dfm}

function ThreadProc(): dword; stdcall;
begin
    asm
      push ecx
      mov ecx,$7FFFFFFF
      @f:
        inc ad
        xor byte ptr[by],$64
        add byte ptr[by],$46
        xor byte ptr[by],$54
        shl byte ptr[by],2
      loop @f
      pop ecx
    end;
    ExitThread(0);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
    ThID[0] :=CreateThread(nil,128*1024,@ThreadProc,nil,0,ThID[0]);
    ThID[1] :=CreateThread(nil,128*1024,@ThreadProc,nil,0,ThID[1]);
    a := GetTickCount();
    WaitForMultipleObjects(2, @ThID, FALSE, INFINITE);
    ShowMessage(IntToStr(GetTickCount() - a));
end;


Как видишь, два потока, в каждом будет выполняться цикл с числом иттераций 7FFFFFFF(2147483647), в общей сложности два потока выполнят 7FFFFFFF*2 = FFFFFFFE иттераций. Измерил и получил наилучшее время выполнения 56.046 сек. 

Учитывая, что код обоих потоков сжох? можно предположить, что они хорошо закешированы и поэтому выполняются так же быстро. 
Так же не учитывается погрешность с которой измеряет время GetTickCount, она составляет ~60 мс.  
Программы запускал по 5 раз каждую, в качестве результат брал наименьшее значение, т.к. оно является самым верным(не среднее).

Счастливым обладателым n-ядерных процессоров предлагаю прочесть справку по SetThreadAffinityMask и, грамотно распараллелив потоки, сделать замер. 

PS AMD Athlon AM2 3500+

Это сообщение отредактировал(а) W4FhLF - 26.7.2007, 17:12


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
Alexeis
Дата 26.7.2007, 17:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



 Ааа сори, не нужно, все и так понятно, вот только условие "НЕТ БЛОКИРУЮЩИХ ОПЕРАЦИЙ" - почти утопия. В компе много устройств и работают они не всегда достачно быстро чтобы обеспечить друг друга данными, из-за чего обычно процессор не используется на 100%, так что если грамотно раскидать на потоки операции, то прирост будет. 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Демо
Дата 27.7.2007, 08:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 7
Всего: 50



Цитата(W4FhLF @  26.7.2007,  17:05 Найти цитируемый пост)
Счастливым обладателым n-ядерных процессоров предлагаю прочесть справку по SetThreadAffinityMask и, грамотно распараллелив потоки, сделать замер. 


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

Добавлено через 1 минуту и 12 секунд
Цитата(W4FhLF @  26.7.2007,  16:53 Найти цитируемый пост)
 для задачи, где НЕТ БЛОКИРУЮЩИХ ОПЕРАЦИЙ,


Почти вырожденный случай.


--------------------
    
PM MAIL ICQ Skype   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1043 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.