Просмотр полной версии : Технология программирования сложных расчетов
Paul Kellerman
14.01.2011, 14:00
Хотелось бы обменятся опытом по следующему интересному вопросу.
Есть некоторый класс задач (поставленный какой-нибудь прикладной
наукой), входные и выходные данны четко определены, метод решения
также известен. Все что требуется - написать программу для расчета,
в которую можно ввести входные данные, выполнить расчет и вывести
результаты. В общем все просто, стандартно и банально до безобразия.
В принципе даже школьник осилит, если метод не особо замороченный.
Также договоримся, что программа пишется под Windows с использова-
нием доступных элементов графического интерфейса пользователя, пре-
доставляемых как самой ОС, так и средой разработки GUI-приложений.
А теперь нюансы... Метод решения может оказаться не особо сложным
для понимания, а вот с вычислительной точки зрения очень трудоемким.
Соответственно, если расчет "долгий", то окно программы "умирает" на
время вычислений, никак не откликаясь на воздействия пользователя.
Соответственно, хотелось бы чтобы программа расчета умела следующее:
1) Не "умирать" при выполнении длительных расчетов и быть "отзывчивой".
2) Предоставлять возможность корректно прерывать расчеты в любой мо-
мент по желанию пользователя, при этом культурно подчищая все хвосты:
освобождая выделенные блоки памяти, закрывая открытые файлы и прочее.
3) Предоставлять возможность следить за текущим состоянием выполняемых
расчетов. В простейшем случае - процент завершенности. В более сложных
случаях - подробная детализация внутреннего состояния решаемой задачи.
У меня, разумеется, за годы выработался свой шаблон для подобных программ,
который, разумеется, включает использование отдельных потоков (thread), но
там есть свои подводные камни и нюансы, вот о них и хотелось бы поговорить.
P.S. Про распараллеливание самого метода решения здесь говорить не будем,
это уже совсем отдельная тема... долгая, нудная, многотомная и бесконечная.
P.P.S. Да чуть не забыл... Все вышеперечисленные "удобства" ни в коим случае
не должны сколь-либо существенно увеличивать общее время решения задачи.
Кроме того, главный поток не должен захлёбываться от прорвы Windows message.
Ну, и, наконец, обойти все случаи, приводящие к dead-lock (взаимоблокировке).
Во-первых, программа должна периодически что называется "отдавать управление" (это справедливо для всех ОС, только конкретный механизм может быть разным), про конкретику чуть ниже.
Во-вторых, такая вычислительная программа состоит, очевидно, как минимум из одного цикла (чаще - из N вложенных циклов). Так вот во время каждой итерации (главного цикла) и следует отдавать управление, а также обновлять индикатор прогресса и т.п.
В-третьих, целесообразнее такую программу организовать как многопоточную, уж во всяком случае выделив в разные потоки (thread) вычислительную часть и GUI.
И наконец, про передачу управления. Если нужно вернуть управление ОС, то в Win32 API это делается посредством ф-ций Sleep(), WaitForXXXX и т.п. Передача управления же от вычислительного потока к GUI-потоку этого же процесса производится путем просматривания очереди сообщений и их направления получателям (по типу того как это делается в ф-ции WinMain).
Paul Kellerman
26.03.2011, 12:50
Что же, прошло достаточно много времени с момента поднятия данной темы.
Хочу поделиться простеньким примером программы, выполняющей "длитель-
ные расчеты", послушать мнения и предложения спецов в программировании.
Суть самой программы простейший: вводите количество испытаний n и веро-
ятность успеха в отдельном испытании p, ну и запускаете расчет, в котором
простым итерационным способом проводится n испытаний и подсчитывается
количество успехов. Параметр n, целое число в пределах от 0 до 999999999,
а p, действительное число (и в качестве разделителя целой и дробной части
используется точка, а не запятая), от 0 до 1. Очевидно, при большом n испы-
тания и подсчет успехов могут затянуться, поэтому требуется особый подход.
Программа написана с использованием традиций объектно-ориентированного
программирования и событийно-ориентированного подхода в Delphi, и к этому
всему добавлен многопоточный подход со всеми вытекающими особенностями.
Исходный код сосредоточен в двух модулях: основном (lm_main.pas) и матема-
тическом (lm_math.pas). Исходный код достаточно подробно закомментирован.
Основные особенности моего подхода в данной программе:
- Математическая обработка выполняется в отдельном потоке SolverThread, ко-
торый запускается в обработчике события нажатия кнопки "Пуск". Далее либо
он самостоятельно завершается (все испытания проведены) либо прерывается
пользователем кнопкой "Стоп", при этом для события завершения потока есть
свой отдельный обработчик, где в частности выводятся результаты испытаний.
- Математическая обработка реализована не как "отдельно-висящая" функция,
а как самостоятельный класс "математического аппарата" (TMathEngine), и он
вынесен в отдельный математический модуль программы (это делает программу
более структурированной и читабельной). Класс содержит конструктор, дест-
руктор, ну и метод (функцию), выполняющую вычисления и испытания в одном
цикле. Вычислительный метод (Solve) при вызове из главного модуля программы
получает не только параметры n и p, но и два указателя: на специальный флаг,
которым можно управлять "извне" для принудительного завершения вычислений,
и на специальную структурную переменную, в которую записывается состояние
матаппарата, для возможности слежения за "ходом" вычислений "извне". В цикле
вычислительного метода на каждой итерации проверяется флаг принудительного
завершения, плюс обновляется структурная переменная состояния матаппарата.
- Для периодического отображения текущего состояния (хода вычислений) мат-
аппарата применен следующий прием. В программе создается специальный тай-
мер UpdateTimer, который с периодом 20 миллисекунд срабатывает и операцион-
ная система посылает главному окну программы Windows-сообщение WM_TIMER.
Это сообщение обрабатывается в главной "оконной" процедуре WndProc, привя-
занной к основному окну программы. При обработке сообщений WM_TIMER, про-
веряется активен ли данный момент поток матобработки, и если да, то считыва-
ется структурная переменная состояния матобработки, вычисляется "прогресс"
(доля завершенности) матобработки и обновляется соответ. полоса прогресса.
P.S. На всякий случай скажу, что это не лучший пример моего программирова-
ния, сам я оцениваю свой подход к реализации сложных расчетов на "четыре".
Некоторые проверки и оптимизации я намеренно удалил, чтобы пример был как
можно проще и короче, но даже с учетом этого получилось около 450 строк :type:
Я бы сделал многонитевой демон, выполняющий собственно рассчёты и простую морду к нему на чём-нибудь вроде PyGTK или Vala. IPC - через d-bus. Это заодно позволило бы избежать потери производительности при рассчётах, вызванной странным требованием "программа пишется под Windows" - благо d-bus и по сети отлично работает.
вызванной странным требованием "программа пишется под Windows"
Вам лет-то сколько ? Вы вообще реальным разработчиком работали когда-нибудь ?
Открою секрет (КО): софт разрабатывается исходя из требований заказчика, а не ваших эротических фантазий. И, согласно этим требованиям, где-то в 90 % случаев как раз "программа пишется под Windows".
saovu, http://aspirantura.spb.ru/forum/showthread.php?p=40141&highlight=matlab#post40141
gav, да я тоже дано заметил, что этому товарисчу присущ технологический экстремизм.
Недавно реализовывал простейший клауд на основе самопального протокола аля XML-RPC (разумеется поверх HTTP).
Вы вообще реальным разработчиком работали когда-нибудь ?
А ты оплачиваемую работу с трёпом на форуме случайно не перепутал?
Впрочем готов приступить к скрупулёзному исполнению требований сразу после получения первой же платёжки :-D
А ты оплачиваемую работу с трёпом на форуме случайно не перепутал?
На брудершафт пили ?
Впрочем готов приступить к скрупулёзному исполнению требований сразу после получения первой же платёжки
Надо ничего не понимать в людях страдать от жестокого дефицита кадров, чтоб начать сотрудничество с таким персонажем как вы.
На брудершафт пили ?
Чур меня! :)
Просто вопросы в духе "скольковамлет" предполагают некоторую неформальность общения, не находишь? ;-)
Если тема еще актуальна, то предлагаю обратить внимание на вычисления с помощью графических процессоров (видеокарт), в частности на технологию CUDA. При грамотном распараллеливании можно получить феноменальную производительность.
предлагаю обратить внимание на вычисления с помощью графических процессоров (видеокарт), в частности на технологию CUDA.
Тогда уж OpenCL чтобы не привязываться к единственному производителю.
vBulletin® v3.8.8, Copyright ©2000-2025, vBulletin Solutions, Inc. Перевод: zCarot