Помощь - Поиск - Пользователи - Календарь
Полная версия: вопросы по потокам....
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Делфи
Snake_B
проведите кто-нибудь ликбез по потокам ))

такие вот вопросы... есть у меня в программе функции обработки картинок... если их вынести в отдельные потоки, будут ли задействованны вторые там ядра у новых процессоров?
(под делфи 2005)
volvo
Цитата
если их вынести в отдельные потоки, будут ли задействованны вторые там ядра у новых процессоров?
Будут. И вторые, и третьи, и четвертые. Этим занимается планировщик Windows. Но можно пошаманить и вручную: SetThreadAffinityMask / SetThreadIdealProcessor.

Дж. Рихтер, "Windows для профессионалов: создание эффективных Win32 приложений с учетом специфики 64-разрядной версии Windows" - это читать в первую очередь. Во вторую - книга Martin Harvey: "Multithreading - The Delphi Way".
Snake_B
Цитата(volvo @ 17.09.2010 9:25) *

Будут. И вторые, и третьи, и четвертые. Этим занимается планировщик Windows. Но можно пошаманить и вручную: SetThreadAffinityMask / SetThreadIdealProcessor.


уже хорошо, спасибо ))

Цитата(volvo @ 17.09.2010 9:25) *

Дж. Рихтер, "Windows для профессионалов: создание эффективных Win32 приложений с учетом специфики 64-разрядной версии Windows" - это читать в первую очередь. Во вторую - книга Martin Harvey: "Multithreading - The Delphi Way".


да не... какое же это хобби, если кучу книжек читать.... да ещё и на англицком ))
Snake_B
Цитата(volvo @ 17.09.2010 9:25) *

Будут. И вторые, и третьи, и четвертые. Этим занимается планировщик Windows. Но можно пошаманить и вручную: SetThreadAffinityMask / SetThreadIdealProcessor.

Дж. Рихтер, "Windows для профессионалов: создание эффективных Win32 приложений с учетом специфики 64-разрядной версии Windows" - это читать в первую очередь. Во вторую - книга Martin Harvey: "Multithreading - The Delphi Way".


ещё вопросики...
а сколько потоков максимально стоит создавать?
и если будет не сколько потоков, а процессор одноядерный, не будет ли от этого программа работать медленне?
volvo
Цитата
а сколько потоков максимально стоит создавать?
Сколько нужно, столько и создавай. Потоки - они не просто так создаются. Скажем, пишешь ты VCL-приложение, и тебе нужно сделать какое-то длительное действие. Напишешь его в том же потоке - получишь "зависание" GUI, пока действие не закончится. Лечится, конечно, костылем ProcessMessages, но проще вынести вычисления в отдельный поток, чтоб они не мешали работе с интерфейсом.

Учти, чем больше потоков ты создашь, тем больше тебе нужно будет заботиться об их взаимодействии. Если же у тебя потоки абсолютно независимы друг от друга (не читают данные из одного файла, не пишут в один файл, и так далее) - то оптимальное число потоков = число ядер * количество процессоров. Будешь делать больше - ускорения вычислений точно не получишь. Больше можно делать только, чтоб не "завешивать" основной поток на время выполнения "длительной" задачи.
Snake_B
Цитата(volvo @ 19.09.2010 23:16) *

Сколько нужно, столько и создавай. Потоки - они не просто так создаются.


да меня и без них устраивает... но думается, что можно ими ускорить обработку (у меня то лично одноядерный))

Цитата(volvo @ 19.09.2010 23:16) *

Скажем, пишешь ты VCL-приложение, и тебе нужно сделать какое-то длительное действие. Напишешь его в том же потоке - получишь "зависание" GUI, пока действие не закончится. Лечится, конечно, костылем ProcessMessages, но проще вынести вычисления в отдельный поток, чтоб они не мешали работе с интерфейсом.


было такое... сделал в отдельной программе на винапи...
сейчас ещё есть отправка отчетов всяких на e-mail... программа во время отправки зависает... но если сделать в потоке, я же его остановить не смогу если что? или смогу?

Цитата(volvo @ 19.09.2010 23:16) *

Учти, чем больше потоков ты создашь, тем больше тебе нужно будет заботиться об их взаимодействии. Если же у тебя потоки абсолютно независимы друг от друга (не читают данные из одного файла, не пишут в один файл, и так далее) - то оптимальное число потоков = число ядер * количество процессоров.


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

Цитата(volvo @ 19.09.2010 23:16) *

то оптимальное число потоков = число ядер * количество процессоров.


вот тут и вопросы возникают... по хорошему получается надо определять индивидуально сколько этих самых
"число ядер * количество процессоров" есть и столько потоков создавать... так?

Цитата(volvo @ 19.09.2010 23:16) *

Будешь делать больше - ускорения вычислений точно не получишь. Больше можно делать только, чтоб не "завешивать" основной поток на время выполнения "длительной" задачи.


да в общем понятно, что быстрее не будет... просто, чтобы не определять количество ядер сделать 4 потока... будет 4 ядра - будет быстрее, не будет - не будет медленне (вот тут и вопрос - не будет ли медленне)....
хотя по хорошему так не правильно, наверно, это счас 4 ядра на топовых... а если через пару лет кто то программу будет использовать и ядер будет 8... лучше наверно определять их количество... да? ))

п.с. и ещё один вопрос не по теме...
вот в DRKB:
Цитата
так как код использует GetTickCount, возвращающий в миллисекундах время с момента старта системы, это необходимо для ежечасной инициализац ии кода выполнения задачи. По-моему это то, что вам нужно. Величина, возвращаемая GetTickCount имеет тип DWORD, но Delphi ее хранит как LongInt, поэтому большие значения могут иметь отрицательную величину (после примерно 25 дней).

у меня программа считает сколько времени она отработала (люблю статистику)) и вот я заметил, что она иногда уходит в минус (я пока не уверен когда именно она это делает).... получается это из этого - "большие значения могут иметь отрицательную величину"? (в общем то других причин там быть не должно).... как с этим можно бороться?

"var TimeLaunchProg: integer;"
при запуске программы "TimeLaunchProg:=GetTickCount;"
при закрытии "Сounter:=GetTickCount - TimeLaunchProg;"
ну и там обработка...
Unconnected
На одноядерном ускорится что-то вряд ли, просто удобнее так как-то..
Цитата

я же его остановить не смогу если что? или смогу?


Сможешь, там методы есть для всего, что нужно.
Цитата

по хорошему получается надо определять индивидуально сколько этих самых
"число ядер * количество процессоров" есть и столько потоков создавать... так?


Это в идеале, так то ты и на одноядерном можешь сколько хочешь потоков создать (в пределах разумного). Одноядерный процессор будет выделять твоему потоку такты своего времени, выхваченные между расчётами для других приложений, получится псевдораспараллеливание (псевдо-т.к. по сути все делается на одном ядре).
Цитата

и вот я заметил, что она иногда уходит в минус


Попробуй int64..
volvo
Цитата
Это в идеале, так то ты и на одноядерном можешь сколько хочешь потоков создать
А теперь - внимание, вопрос: А сколько это - в пределах разумного? smile.gif Сколько потоков я могу создать в своей программе? Но это оффтоп, отвечать можно в теге Hide, если что...

Теперь по теме:
Цитата
по хорошему получается надо определять индивидуально сколько этих самых
"число ядер * количество процессоров" есть и столько потоков создавать... так?
По хорошему - получается, что ПРОСТО ТАК создавать ничего не надо, тем более на одноядернике. Увеличить скорость не получится однозначно, скорость только уменьшится, зачем тебе проблемы? Определяй количество ядер/процессоров на машине (если что - можно прочесть системную переменную NUMBER_OF_PROCESSORS), и создавай поток(-и), обрабатывающие информацию только если это число больше 1. Больше конкретики, если можно, что за потоки, какую задачу выполняют? Чего ты вдруг решил что-то выносить в отдельный поток?

Цитата
сейчас ещё есть отправка отчетов всяких на e-mail... программа во время отправки зависает...
Программа зависает по какой причине? Потому что долго выполняется и потом, когда отправится - все-же "отвисает"? Или зависло, и с концами? Если "отвисает" - то выноси в отдельный поток.

Цитата
но если сделать в потоке, я же его остановить не смогу если что? или смогу?
Если "что"? Поток должен сам знать, когда ему завершиться, а когда - нет. Когда завершится - тогда и завершится. Если правильно напишешь Execute - будет работать правильно. Откуда ты собрался "если что" его останавливать?

Добавлено через 1 мин.
Цитата
Попробуй int64..
Не надо... Опять нарушаем сигнатуру функции?
Цитата
DWORD WINAPI GetTickCount(void);
, вот и пользуй DWORD...
Snake_B
Цитата(volvo @ 20.09.2010 9:40) *

Теперь по теме:
По хорошему - получается, что ПРОСТО ТАК создавать ничего не надо, тем более на одноядернике. Увеличить скорость не получится однозначно, скорость только уменьшится, зачем тебе проблемы? Определяй количество ядер/процессоров на машине (если что - можно прочесть системную переменную NUMBER_OF_PROCESSORS), и создавай поток(-и), обрабатывающие информацию только если это число больше 1. Больше конкретики, если можно, что за потоки, какую задачу выполняют? Чего ты вдруг решил что-то выносить в отдельный поток?


программа сжимает изображения в папке... решил выносить, чтобы на многоядерных работала (сжимала) быстрее...

Цитата(volvo @ 20.09.2010 9:40) *

Программа зависает по какой причине? Потому что долго выполняется и потом, когда отправится - все-же "отвисает"? Или зависло, и с концами? Если "отвисает" - то выноси в отдельный поток.


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

Цитата(volvo @ 20.09.2010 9:40) *

Если "что"? Поток должен сам знать, когда ему завершиться, а когда - нет. Когда завершится - тогда и завершится. Если правильно напишешь Execute - будет работать правильно. Откуда ты собрался "если что" его останавливать?


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

Цитата(volvo @ 20.09.2010 9:40) *

Добавлено через 1 мин.
Не надо... Опять нарушаем сигнатуру функции?
, вот и пользуй DWORD...


гм... а я уже переделал... работает всё...
а с DWORD опять поплыло куда то... не верные значения выдает...
может уж, работает, да и фиг с ним? ))
Snake_B
и снова вопросы ))
не совсем про потоки... но думаю тему отдельную создавать не стоит...

есть программа... RedForce.SB – мод для игры Civilization 4: Beyond The Sword (Эпоха огня)...
сначала в программе выбираем необходимые изменения, потом генерируется мод...
используется:

1 копирование файлов:
function WindowsCopyFile(FromFile, ToDir : string) : boolean; // Внутренняя функция...
var F : TShFileOpStruct;
begin
result:=true;
F.Wnd := 0;
F.wFunc := FO_COPY;
FromFile:=FromFile+#0;
F.pFrom:=pchar(FromFile);
ToDir:=ToDir+#0;
F.pTo:=pchar(ToDir);
F.fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION;
result:=ShFileOperation(F) = 0;
end;


2. обрабатываются XML файлы...
так как когда начинал делать парсеры не нашел, то сделал так: в скрытый Tmemo считывается содержание файла, потом с ним идёт работа... так как так получалось довольно медленно, каждый раз приходись искать по всему файлу, то сделал, чтобы при открытие XML-файла в другом TMemo создавался список начальных(~) тегов... и при внесении изменений уже поиск нужной строки шел только в нужном блоке... скорость значительно выросла...

это как введение))
теперь вопросы...

1. эта функция копирования создает стандартное окно копирования Windows... и активирует его... так как генерация довольно долгая, то пользователь может заниматься чем то другим... а это активное окно копирование открывается с выделенной по умолчанию кнопкой "отмена"... и если не заметишь и нажмешь Enter, то копирование сбрасывается...
можно как-нибудь (по проще чтобы))) сделать, чтобы это окно при создании не становилось активным?

п.с. так... видимо сам нашел... "FOF_SILENT"

2. Собственно это основной вопрос...
пришли отзывы от пользователей о времени генерации, вот такие:

Цитата
Процессор Core2Duo 2.53 2-ух ядерный, мод генерировался не менее 40 минут
Проц дуал коре 2.20 - 32 мин. (виндовс виста)
Core 2 Duo E6750 2,66GHz - не меньше часа. (виндовс XP SP2)
Сгенерировал , по часам 9 минут - Athlon !! x3 2.8 ghz. Win 7


и в чём собственно заковыка.... вот это про мой комп:
Цитата
У меня центрино (одноядерный) 2,13 ггц с включением всех настроек генериует 15 минут... виндовс XP SP3

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

п.с. делфи 2005... если что...
мисс_граффити
а "узкое место", думаешь - процессор? не память?

ну и первое что в голову приходит - что запущенно параллельно?
Snake_B
Цитата(мисс_граффити @ 11.10.2010 21:40) *

а "узкое место", думаешь - процессор? не память?


ну... по крайней мере у одного озу 2 гига... у меня столько же... так что вряд ли...
ну и основное время это обработка XML (нагрузка на процессор) и копирование папок... в копировании папок больших файлов практически нет... много маленьких.. так что озу вряд ли будет сильно влиять...
ну и плюс у меня то bds запущена... а она у меня до полугига памяти отжирает ))

п.с. ещё у одного 4 гига, но XP видит только 3,25... генерировал почти без нагрузки и с запущенной игрой.. результаты одинаковые...

Цитата(мисс_граффити @ 11.10.2010 21:40) *

ну и первое что в голову приходит - что запущенно параллельно?


не... ну если бы на одном было так, тогда может быть... но чтобы три пользователя параллельно какое-нибудь архивирование запускали... это вряд ли..
TarasBer
> программа сжимает изображения в папке...

А покажи код самого сжатия.
Snake_B
Цитата(TarasBer @ 12.10.2010 4:36) *

> программа сжимает изображения в папке...

А покажи код самого сжатия.


Delphi Russian Knowledge Base
from Vit
Version 3.0

поиск:
Алгоритм качественного Resize'a, если точнее, то уменьшения
TarasBer
У меня тут нет DRKB и канал маловат, чтоб лишние 10М качать.
Приведи сюда, если там Canvas.StretchDraw, то оптимизировать нечего.
Если очень много вызовов ScanLine...
Я просто к тому, может само сжатие неоптимально? Если просто скопировать файл, не меняя, тормоза останутся?
volvo
Вопрос не в оптимизации, если что. Вопрос - почему одно и то же, уже откомпилированное приложение на одно-ядерниках работает быстрее, чем на двух-... Если оно на
Цитата
центрино (одноядерный) 2,13 ггц
работает за 9 минут, а на
Цитата
Core 2 Duo E6750 2,66GHz - не меньше часа.
- то "что-то неладно в Датском Королевстве" (С)

Snake_B, тут дело все в ОС. Смотри, вот те данные, которые ты привел в порядке увеличения времени выполнения:

Цитата
Сгенерировал , по часам 9 минут - Athlon !! x3 2.8 ghz. Win 7
центрино (одноядерный) 2,13 ггц с включением всех настроек генериует 15 минут... виндовс XP SP3
Проц дуал коре 2.20 - 32 мин. (виндовс виста)
Процессор Core2Duo 2.53 2-ух ядерный, мод генерировался не менее 40 минут
Core 2 Duo E6750 2,66GHz - не меньше часа. (виндовс XP SP2)
Чувствуешь? Win7, WinXP SP3, WinXP SP2. Виста никогда не была той ОСью, на которой выполнялись правила - она вроде бы должна была работать быстрее WinXP, но на самом деле этого не происходило, что и отражается в последовательности. Какая ОС была у того, кто запускал под E6750? Тоже XP2, наверняка. Так что тут надо смотреть всю программу, а не ползать по отдельным алгоритмам в надежде тут сэкономить такт, а тут - три... Ни один ни три такта, отобранные у алгоритма, картины не изменят. Урвешь такт под WinXP SP2 - еще чего доброго будет медленней работать под SP3 или под Семеркой.

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

P.S. Конечным пользователям передается Debug, или Release-сборка? У себя запускаешь какую сборку? Кстати, если программа активно копирует файлы - то от харда тоже может многое зависеть.
TarasBer
> Так что тут надо смотреть всю программу, а не ползать по отдельным алгоритмам в надежде тут сэкономить такт, а тут - три...

Скорость StretchDraw по сравнению с кучей Pixels[,] - это не три такта, это разница на один-два порядка.
Если программа состоит только из FindNext; LoadFromFile; StretchDraw; SaveToFile, то какая разница, Debug или Release?
Это конечно, если дело в самом процессе сжатия. Если не в нём - значит не в нём.
Я потому и спросил, тупо скопировать - тоже долго?

Кстати, алгоритм из DRKB умеет бороть лесенки при кратном сжатии? StrechBlt в WinXP - увы, нет.
Snake_B
> Кстати, алгоритм из DRKB умеет бороть лесенки при кратном сжатии? StrechBlt в WinXP - увы, нет.

умеет... там разные есть...

Цитата
Скорость StretchDraw по сравнению с кучей Pixels[,] - это не три такта, это разница на один-два порядка.
Если программа состоит только из FindNext; LoadFromFile; StretchDraw; SaveToFile, то какая разница, Debug или Release?
Это конечно, если дело в самом процессе сжатия. Если не в нём - значит не в нём.
Я потому и спросил, тупо скопировать - тоже долго?


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

Цитата
P.S. Конечным пользователям передается Debug, или Release-сборка? У себя запускаешь какую сборку? Кстати, если программа активно копирует файлы - то от харда тоже может многое зависеть.


Сборка у всех одинаковая.... хард... вряд ли... больше процессор грузит...

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


ну примерно ясно... задал вопрос какие ОС используют... как ответят отпишусь...
логирование делать не буду... пользователей в общем и час устраивает... я то и узнал про это чисто случайно... опять же дальше программа развиваться особо не будет... мод для цивы 4-ой, а счас уже 5-ка вышла....

> Dual-Core E5300 2600/2600 далеко не новый проц, 10минут
вот ещё один отзыв...

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

п.с...
>> Какая ОС была у того, кто запускал под E6750? Тоже XP2, наверняка.
> windows 7
Snake_B
Цитата(volvo @ 12.10.2010 19:07) *

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


ради интереса отключил копирование... оно через одну функцию вызывается, отключить просто... скорость не изменилась... получается работа с tmemo... хмл в них генерируются...
volvo
Цитата
получается работа с tmemo... хмл в них генерируются...
Я надеюсь, хотя бы BeginUpdate/EndUpdate для Memo используются? А вообще - гадать, из-за чего это может быть, не зная ни структуры программы ни алгоритмов, с которыми она работает, ни собственно обрабатываемых файлов, мне порядком поднадоело. Тем более с отзывами:
Цитата
может уж, работает, да и фиг с ним? ))

Цитата
пользователей в общем и час устраивает...


Google -> "Форумы гадалок и чревовещателей" в помощь...
Snake_B
Цитата(volvo @ 3.01.2011 1:11) *

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


да нет.... это я просто удивился... что ле...
мемо там скрытые... думаю им BeginUpdate/EndUpdate не нужны...
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.