Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.03.27;
Скачать: [xml.tar.bz2];

Вниз

Увеличится ли скорость в моём случае если я сделаю 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.58 MB
Время: 0.042 c
1-1110970095
СержК
2005-03-16 13:48
2005.03.27
Как отобразить на форме рисунок


3-1109769208
Arazel
2005-03-02 16:13
2005.03.27
А что лучше использовать AdoDataSet или AdoQuery?


1-1110465314
Zahar
2005-03-10 17:35
2005.03.27
Использование индекса в именах компонентов...


3-1109252059
Alex--
2005-02-24 16:34
2005.03.27
Ошибка при загрузке файла в TClientDataSet


1-1110387927
Игнатенков Станислав
2005-03-09 20:05
2005.03.27
Типизированные файлы





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский