Форум: "Основная";
Текущий архив: 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