Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.03.27;
Скачать: CL | DM;

Вниз

Увеличится ли скорость в моём случае если я сделаю 2 потока?   Найти похожие ветки 

 
rolex   (2005-03-08 18:45) [0]

Моя прога предположим ищет файлы на винте. Увеличится ли скорость общего поиска, если я его разобью на 2 потока?


 
Anatoly Podgoretsky ©   (2005-03-08 18:47) [1]

Уменьшится и возможно сильно. Операция перемещения головок очень медленная.


 
Antonn ©   (2005-03-08 18:51) [2]

Может мелось ввиду, что поиск будет идти во втором потоке, а в первом интерфейсная часть? Думаю, прога работать будет быстрее.


 
Anatoly Podgoretsky ©   (2005-03-08 19:04) [3]

И в этом случае разницы не заметить, Операция перемещения головок очень медленная и остальные файловые функции не блещут скоростью. Потоки будут просто простаивать, но все равно потребуется дополнительное время на синхронизацию.


 
Набережных С. ©   (2005-03-08 19:06) [4]


> Anatoly Podgoretsky ©   (08.03.05 18:47) [1]

Ну почему обязательно так? Если винт использует ПДП, а сейчас трудно найти не такой, то скорость увеличится. Тем более, что и процессоров может быть несколько. Разумеется, при грамотной организации всего процесса.


 
rolex   (2005-03-08 19:07) [5]


> Anatoly Podgoretsky ©   (08.03.05 18:47) [1]
> Уменьшится и возможно сильно. Операция перемещения головок
> очень медленная.

А как тогда увеличить скорость поиска?


> Antonn ©   (08.03.05 18:51) [2]
> Может мелось ввиду, что поиск будет идти во втором потоке,
> а в первом интерфейсная часть? Думаю, прога работать будет
> быстрее.

Да нет. У меня в процедуре поиска Application.ProcessMessages через каждую строчку понатыкано, поэтому прога у меня не тормозит.


 
rolex   (2005-03-08 19:09) [6]


> Набережных С. ©   (08.03.05 19:06) [4]
>
> > Anatoly Podgoretsky ©   (08.03.05 18:47) [1]
>
> Ну почему обязательно так? Если винт использует ПДП, а сейчас
> трудно найти не такой, то скорость увеличится. Тем более,
> что и процессоров может быть несколько. Разумеется, при
> грамотной организации всего процесса.

Неет... :)) Процессор один. А прога рассчитана на стандартный домашний комп. А что такое "ПДП"? Ниразу не слышал о такой технологии.


 
Anatoly Podgoretsky ©   (2005-03-08 19:10) [7]

rolex   (08.03.05 19:07) [5]
Грамотным построение программы, но увеличить практически невозможно, диски это медленное устройство. Кешируй, не ищи во всю глубину, используй предсказания и так далее.


 
Antonn ©   (2005-03-08 19:19) [8]


> ПДП

DMA?


 
Набережных С. ©   (2005-03-08 19:20) [9]


> rolex   (08.03.05 19:09) [6]

ПДП - прямой доступ к памяти, DMA по-нынешнему. Например, один поток занимается обменом с диском, второй собственно обработкой. Пока первый ждет, второй много что успеет сделать. Да и первый можно занять, пока идет обмен с диском.


 
Anatoly Podgoretsky ©   (2005-03-08 19:23) [10]

Набережных С. ©   (08.03.05 19:20) [9]
Ну ему то не это надо ускорить, не паралельные вычисления, а поиск на диске. Тут два потока дадут замедление из-за постоянного движения головок туда сюда.


 
Набережных С. ©   (2005-03-08 19:27) [11]

Переключение потоков конечно время займет, но NT - не 9х, тут это довольно шустро. Я как-то делал кучу тестов, так на достаточно длительной операции разницы между выполнением ее одним потоком или несколькими, практически нет, в пределах погрешности измерений.


 
Набережных С. ©   (2005-03-08 19:32) [12]


> Anatoly Podgoretsky ©   (08.03.05 19:23) [10]

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


 
Anatoly Podgoretsky ©   (2005-03-08 19:33) [13]

Набережных С. ©   (08.03.05 19:32) [12]
Смотри 7


 
Набережных С. ©   (2005-03-08 19:35) [14]


> Anatoly Podgoretsky ©   (08.03.05 19:33) [13]

Совершенно согласен. Но одно другого, имхо, не отменяет.


 
Anatoly Podgoretsky ©   (2005-03-08 19:48) [15]

Набережных С. ©   (08.03.05 19:35) [14]
Вот когда будет другая предпосылка, чем в данном вопросе, тогда можно будет и о другом поговорить, а в данной постановке замедление и снижение надежны работы, из-за уровня знаний.


 
Набережных С. ©   (2005-03-08 19:53) [16]


> Anatoly Podgoretsky ©   (08.03.05 19:48) [15]
>  а в данной постановке замедление и снижение надежны работы,
> из-за уровня знаний.

:)))


 
Sphinx ©   (2005-03-08 20:13) [17]

А может попробовать использовать службу индексирования в NT-системах...или она только в ХР есть...или тольно на NTFS...запамятовал...???
Но включение индексирования действительно ускоряет поиск...


 
rolex   (2005-03-08 21:01) [18]


> Sphinx ©   (08.03.05 20:13) [17]
> А может попробовать использовать службу индексирования в
> NT-системах...или она только в ХР есть...или тольно на NTFS...запамятовал...???
> Но включение индексирования действительно ускоряет поиск...

Поподробнее пожалуйста...


 
Дмитрий Мыльников   (2005-03-08 21:02) [19]

А в чём, собственно, заключается поиск-то? Если просто по имени файла в файловой системе, то тут основную работу будет делать OC, так что многопоточность ничего не даст. Если же производится ещё и анализ внутренних данных в самих файлах, то тогда многопоточность при небольшом количестве потоков может ускорить работу программы. Пока один поток получает данные, другие будут заняты анализом.

Что же касается кэширования, то мне кажется, что в данном случае это не сильно поможет, поскольку кэширование даёт выигрыш при многократном обращении к одним и тем же данным, что нехарактерно для поиска.


 
rolex   (2005-03-08 21:06) [20]


> ...Если просто по имени файла в файловой системе...

Именно это и делает моя программа.
Т.е. по вашим словам FindFirst и FindNext - быстрее уже ничего нереально сделать. Так?


 
Erik1 ©   (2005-03-09 11:15) [21]

В отдельный поток всеравно стоит вынести и отделить от нитерфейсной части. Структура программы станент более правильной и Application.ProcessMessage ненадо будет тыкать везде где возможно. А вобще еденичный поиск происходит относительно быстро, в ускорении процеса тебе может помочь другая логическая организация. Попробуй полностью изложить постаноыку задачи.


 
rolex   (2005-03-09 13:03) [22]

Аааа.... столько текста набирал!!! Всё стёрлось! Заново писать уже сил нету. Короче вот процедура поиска (выдрал прямо из исходников без изменения), если разберётесь конечно:
procedure ScanDrive(const DirName, Mask :String);
 procedure ScanDirs(const DirName :String);
 var
   h   :tHandle;
   wfd :tWin32FindData;
   s,i,iskl:integer;
   sizeDir:TLargeInteger;
 begin
 Application.ProcessMessages;
 form1.Label2.Caption:="Поиск в "+DirName;
   h := Windows.FindFirstFile(PChar(DirName+Mask), wfd);
   try
     if (h<>INVALID_HANDLE_VALUE) and (Not((DirName=Form2.Edit1.Text)and(Form2.RadioButton3.Checked=True))) then begin
       repeat
         Application.ProcessMessages;
         if  ((wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY)=0) then begin
           for s:=0 to Form2.CheckListBox2.Count - 1 do begin
             Application.ProcessMessages;
             if (Form2.CheckListBox2.Checked[s]) and (Form1.FScanAborted=false) and (MatchesMask(wfd.cFileName, Form2.CheckListBox2.Items[s])=true) and (HaveCopyItem(DirName+wfd.cFileName)=False) then
             if (MatchesMask(wfd.cFileName, Form2.CheckListBox2.Items[s]))=true then //-- Двойная проверка
             begin
               iskl:=0; //-- Проверка на исключения
               for i:=0 to Form2.ListBox1.Count-1 do if (MatchesMask(wfd.cFileName, Form2.ListBox1.Items[i]))=true then begin iskl:=1; if HaveCopyItemOnExclusion(DirName+wfd.cFileName)<>true then with Form5.ListView1.Items.Add do begin Caption:=DirName+wfd.cFileName; SubItems.Add(Form2.CheckListBox2.Items[s]); SubItems.Add(Form2.ListBox1.Items[i]); end; end;
               if iskl<>1 then
               begin
               form1.CheckListBox1.Items.Add(DirName+wfd.cFileName);
               chetchik:=chetchik+1;
               Form1.label14.Caption:=IntToStr(StrToInt(Form1.label14.Caption)+1);
               fsize:=fsize+GetFileSize(DirName+wfd.cFileName);
               ToShowSize;
               end else Form1.label1.Caption:=IntToStr(StrToInt(Form1.label1.Caption)+1);
             end;
           end;
         foundedsize:=foundedsize+GetFileSize(DirName+wfd.cFileName);
         form1.ProgressBar1.width:=((form1.Width-12)div 100)*(100*foundedsize div allsize+1);
         form1.Image9.Left:=form1.ProgressBar1.width+form1.ProgressBar1.left;
         end;
       until  (not Windows.FindNextFile(h,wfd)) or (Form1.FScanAborted=true);
     end else if (DirName=Form2.Edit1.Text)and(Form2.RadioButton3.Checked=True) then begin SizeDir:=0; GetDirSize(DirName, SizeDir); foundedsize:=foundedsize+SizeDir; end;
   finally
     if  h <> INVALID_HANDLE_VALUE  then Windows.FindClose(h);
   end;
   Application.ProcessMessages;
   // Теперь рекрсивно просмотрим подкаталоги
   h := Windows.FindFirstFile(PChar(DirName+"*.*"), wfd);
   try
   Application.ProcessMessages;
     if  h <> INVALID_HANDLE_VALUE  then begin
       repeat
         Application.ProcessMessages;
         if   ((wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0)
          and (wfd.cFileName <> String("."))
          and (wfd.cFileName <> "..")           then
           ScanDirs(IncludeTrailingPathDelimiter(DirName+wfd.cFileName));
           Application.ProcessMessages;
       until  (not Windows.FindNextFile(h,wfd)) or (Form1.FScanAborted=true) or (Application.Terminated);
     end;
   finally
     if  h <> INVALID_HANDLE_VALUE  then Windows.FindClose(h);
   end;
 end;
begin // FindFilesByMask
 ScanDirs(IncludeTrailingPathDelimiter(DirName));
 Application.ProcessMessages;
end;


 
raidan ©   (2005-03-09 13:13) [23]

Увеличить скорость можно, если есть несколько дисков как физических устройств и читать параллельно с них. Хотя это уже извращения. Кому нужна большАя скорость - тот сделает себе RAID-0.


 
Digitman ©   (2005-03-09 13:40) [24]


> Application.ProcessMessages через каждую строчку понатыкано


не "тыкай" сабж где ни попадя - будет тебе существенное увеличение сквозной производительности

оптимизируй свой алгоритм, удалив множественные явные именованые обращения к одним и тем же идентификаторам, используя взамен этого оператор with - будет дополнительное увеличение сквозной производительности

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

да мало ли чего еще тут можно оптимизировать ! ... судя по коду - просто поле непаханое ..

в конце-концов - переделать алгоритм целиком, читая каталоговую структуру однократно, а затем фиксируя лишь события ее изменения


 
Erik1 ©   (2005-03-09 15:39) [25]

И рекурсию можно убрать, тоже производительность увеличится( http://www.codenet.ru/progr/other/prbook/gl8.php )


 
rolex   (2005-03-09 16:56) [26]


> не "тыкай" сабж где ни попадя - будет тебе существенное
> увеличение сквозной производительности

А где лишние Application.ProcessMessages в моём коде???


> оптимизируй свой алгоритм, удалив множественные явные именованые
> обращения к одним и тем же идентификаторам, используя взамен
> этого оператор with - будет дополнительное увеличение сквозной
> производительности

Т.е. это значит в, например, коде:
Form1.width:=...;
form1.height:=...;
form1.title:=...;
Мне нужно сделать так:
with Form1 do
begin
width:=...;
height:=...;
title:=...;
end;

я так понял?


> минимизируй строковые операции - будет тебе приращение той
> же произв-ти за счет меньшего числа перераспределений памяти
> встроенным менеджером памяти

Не понял... можно по подробнее.


> в конце-концов - переделать алгоритм целиком, читая каталоговую
> структуру однократно, а затем фиксируя лишь события ее изменения

Это я тоже не понял. Объясните плз!!!


 
Дмитрий Мыльников   (2005-03-09 21:49) [27]

Ну на счёт всякой оптимизации через with и прочее, это когда явные тормоза уберёшь. А так особо и не заметишь. :)

Во-первых, как уже было сказано, не нужно Application.ProcessMessages вызывать в каждом повторении цикла. Заведи счётчик, и в конце цикла напиши что-то типа

int(I);
if (i mod 100) = 0 then Application.ProcessMessages;
То есть, вызывай его один раз на 100 проходов цикла (оптимальное число подбирается путём натурных испытаний). Плюс, в конце функции тоже можно, поскольку она у тебя рекурсивная.
Кстати, от рекурсии я бы не стал отказываться, поскольку так код выглядит проще, а существенного ускорения на древовидной структуре всё равно с помощью других алгоримтов не получить. Зато код будет более сложным.

Во-вторых, и это на мой взгляд самое главное - желательно собрать всю информацию во внутренних переменных, а уже потом переносить их в компоненты форм. А если по логике программы это сделать нельзя, то при массовых операциях очень рекомендуется делать следующее

<компонент>.Items.BeginUpdate;
try
  ... тут вносим массовые изменения в Items
finally
  <компонент>.Items.EndUpdate;
end;

Фишка в том, что после вызова BeginUpdate блокируется вызов обновления компонента на экране до тех пор, пока не будет вызвана EndUpdate, которая и отобразит все изменения сразу. А сейчас у тебя получается, что каждое добавление строки запускает весьма длительный код по обновлению компонента на экране.


 
Knight ©   (2005-03-09 22:24) [28]

На собственном опыте убедился, что всякие там Application.ProcessMessages и ProgressBar"ы, тормозят процесс в несколько раз... чем реже, тем быстрее... :)


 
Fay ©   (2005-03-09 22:43) [29]

Что-то не верится, что with-ом можно ускорить поиск.


 
rolex   (2005-03-10 12:28) [30]

Вернёмся к потокам.
Вот схема (по моим предположениям):
1) Сейчас прога так сканирует:
Сканирование  |- - - - |
Др. обработка | - - - -|


2) Если сделать 2потока (1й на скан, 2й на др. обработку):Сканирование  |---- |
Др. обработка | ----|


Т.е. в первом случае сканируется файл, прога ждёт; потом прога смотрит (проверяет) файл, "сканирование" ждёт.

Во втором случае, всё идёт параллельно и нету практически никаких ожиданий, ни с той стороны, ни с другой.

Вывод: Во втором случае времени на общее сканирование (включая обработку) потребуется времени почти в два раза меньше!

*Под обработкой понимается сверка имения файла со списком масок и т.д.

Правильны ли мои рассуждения???


 
Digitman ©   (2005-03-10 13:33) [31]


> rolex   (08.03.05 18:45)  
> Моя прога предположим ищет файлы на винте


ну и пусть себе ищет !
зачем каждый найденный файл тут же изображать юзеру ? вот это непонятно ..

ну сформируй ты данные все разом, а потом изобрази их юзеру готовыми ! зачем рисовать по одному элементу за одну итерацию-то ? вот это непонятно ..


 
Erik1 ©   (2005-03-10 13:43) [32]

to rolex
Твои расждения правильны, если обработка занимает хотябы 500mc. К томуже такой подход позволит привести в порядок твой ужаствый код. Все обащения к VCL придется выкинуть и заменить их перемеными.


 
rolex   (2005-03-10 19:06) [33]

Тоесть второй вариант стоит осуществить?


> Все обащения к VCL придется выкинуть и заменить их перемеными.

Всмысле?


 
rolex   (2005-03-11 11:21) [34]

Ау!!! На вопросики то ответьте!!!


 
Anatoly Podgoretsky ©   (2005-03-11 12:06) [35]

Как опять?


 
Erik1 ©   (2005-03-11 12:23) [36]

Да что непонятного то? Например:
Form1.label14.Caption:=IntToStr(StrToInt(Form1.label14.Caption)+1);
Нахрен сносим и пишем Inc(Count); где Count: Integer;
Еще пример: Form2.ListBox1.Items[i] тоже убрать и заменить на TList в который заносим record. Надеюсь структуру record сам опишеш?!
ВСЕ ОБРЕЩЕНИЕ К VCL(Form, ListBox, пр..) ВЫКИНУТЬ!


 
rolex   (2005-03-11 18:55) [37]

А второй вариант стоит осуществить?


 
vertal ©   (2005-03-11 22:10) [38]

Запускай процедуру поиска и анализа имен файлов в отдельном потоке. В ней не должно быть никаких обращений к интерфейсу, и эта процедура должна быть полностью изолированной от остальной программы (связь только черз параметры). При нахождении нового подходящего файла кидай его имя в потокобезопасную очередь. Прикладные программы видимо должны считать, что FindFirst/FindNext - это предел скорости, так что с этой стороны оптимизация вряд ли возможна. Вместо MatchesMask создавай заранее необходимое число объектов TMask. Если выяснится, что узкое место - в операции проверке соответствия множеству масок, то можно попробовать сделать процедуру формирования конечного автомата, который будет проверять имя файла на соответсвие сразу любой из масок. В главном потоке по таймеру опустошай потокобезопасную очередь и выводи ее содержимое в контрол.
А код из [22] выглядит просто жутко:
Дикие имена переменых, отсутствие изоляции от остальной программы и от интерфейса, ProcessMessages понатыкано везде, лишние операции в цикле...
Это по-моему проще переписать.


 
rolex   (2005-03-12 20:14) [39]

Осуществил второй вариант (Сканирование в одном потоке, а обработка и интерфейс проги в другом потоке). В результате чего время сканирования увеличилось с 5мин. до 7мин. !!! =O


 
rolex   (2005-03-12 20:15) [40]

Осуществил второй вариант (Сканирование в одном потоке, а обработка и интерфейс проги в другом потоке). В результате чего время сканирования увеличилось с 5мин. до 7мин. !!! =0



Страницы: 1 2 3 вся ветка

Текущий архив: 2005.03.27;
Скачать: CL | DM;

Наверх




Память: 0.59 MB
Время: 0.219 c
1-1111052504
Gerakl
2005-03-17 12:41
2005.03.27
Delphi2005 (IDE)


14-1109876476
Kolan
2005-03-03 22:01
2005.03.27
Как редактировать свою запись на форуме?


11-1092829854
omegaB
2004-08-18 15:50
2005.03.27
Передача файла с использованием KOLICS - KOLWSocket


8-1102970064
pika
2004-12-13 23:34
2005.03.27
Рисование


1-1110881847
Ozone
2005-03-15 13:17
2005.03.27
Обработка исключительных ситуаций