Страниц: [1]
  Печать  
Автор Тема: Разработчику: QNX: Многомашинные вычисления.  (Прочитано 11700 раз)
olej
QOR.Team
****
Offline Offline

Сообщений: 42



Просмотр профиля
« : Ноября 15, 2002, 11:10:00 pm »

Статья об организации многомашинной обработки (кластера) используя специфичные средства QNX & QNET: http://qnx.org.ru/docs-devel/cluster.html.

В статье описывается работа программной реализации распределённых вычислений единой задачи на нескольких компьютерах в сети QNET, сам проект: http://ftp://ftp.qnx.org.ru/pub/projects/olej/cluster.1.12.tgz.

В реализации использованы специфические особенности QNX/QNET - обмен сообщениями через микроядро. За счёт этого - самой уникальной стороной предложенной реализации является её размер, организация кластерных вычислений потребовала около 300 строк специфического кода (всё остальное - рутина).

Описана реализация многомашинной обработки произвольно выбранной конкретной (тестовой) задачи: "поиск ключей шифрования". Но по той же схеме (чуть ли не текстуально используя фрагменты программного кода проекта) можно организовать параллельное выполнение почти любой задачи из класса "хорошо распараллеливаемых" задач.


[ Это Сообщение было отредактировано: Olej в 2002-11-15 20:13 ]
Записан
kot
Гость
« Ответ #1 : Ноября 19, 2002, 06:36:00 pm »

Я безусловно согласен с тем что QNX это resource manager (resmgr) в первую очередь, но согласитесь, однобокость тоже не к чему, если абсолютно все сводить к написанию resmgr, то думаю, сложновато будет. Как мне показалось, данную задачу, которую решает Олег, лаконичнее реализовать без использования явного resmgr на стороне агента. Pipes явно недооценены, а точнее их применяемость в QNX (безусловно это resmgr но в понятиях POSIX). Дмитрий в своей статье "Утилита On" уделял внимание функции spawn, а там есть очень замечательный параметр map_fd который как раз и поможет решить задачу распараллеливание в более привычных терминах, не вдаваясь в специфику resmgr. Совсем упрощенный вариант реализации распределенного по сети кода только средствами spawn и pipes представлен здесь.
Планировщик абсолютно не интеллектуален и просмотрев сеть запускает единственного агента на последнем узле из полученного списка.
В качестве "очень сложной" задачи агента используется умножение сложением с задержкой nanospin.

Данный подход, по моему мнению, позволяет:

  • Не использовать resmgr, а значит и права root в задачах агентов.
  • Использовать агентов без каких-либо изменений в других вариантах (например inetd).
  • Оставаться ближе к POSIX.

Записан
dmi
QOR.Admin
*****
Offline Offline

Сообщений: 469



Просмотр профиля
« Ответ #2 : Ноября 19, 2002, 06:47:00 pm »


kot пишет:
Совсем упрощенный вариант реализации распределенного по сети кода только средствами spawn и pipes представлен здесь.


Ага, вот тут сразу два вопроса по тексту:

 if (inherit.nd > 0)
   inherit.flags = SPAWN_SETND;

В примерах для статьи я устанавливал флаг SPAWN_EXEC. Без него все обрабатывалось чоень криво. Этот пример пока не опробовал. Вопрос: необходим этот флаг при удаленном запуске или нет.

Вопрос # два:

 pipe (pipe_fd);
 fdsmap[1] = pipe_fd[1];
 pfdr = pipe_fd[0];        //STDOUT
 fdsmap[2] = pipe_fd[1];   //STDERR

Не лучше ли оперировать с файловыми дескрипторами вызовом dup() ?
Записан
kot
Гость
« Ответ #3 : Ноября 19, 2002, 07:28:00 pm »

В примерах для статьи я устанавливал флаг SPAWN_EXEC. Без него все обрабатывалось чоень криво. Этот пример пока не опробовал. Вопрос: необходим этот флаг при удаленном запуске или нет.

Предполагаю, что использование SPAWN_EXEC фактически "выжмет" родительский
процесс и тогда для продолжения действий стоит использовать fork(), а как известно fork() и threads() пока не совместимы, по этому в данной задаче прменение SPAWN_EXEC катастрофично. У меня все прекрасно работает в том варианте, который представлен.

Не лучше ли оперировать с файловыми дескрипторами вызовом dup() ?

Думаю, что заменить на

fdsmap[2] = dup(fdsmap[1]);

не помешает, а работать все будет как и прежде.

[ Это Сообщение было отредактировано: kot в 2002-11-19 16:31 ]
Записан
olej
QOR.Team
****
Offline Offline

Сообщений: 42



Просмотр профиля
« Ответ #4 : Ноября 19, 2002, 08:26:00 pm »


kot пишет:
Pipes явно недооценены, а точнее их применяемость в QNX (безусловно это resmgr но в понятиях POSIX). Дмитрий в своей статье "Утилита On" уделял внимание функции spawn, а там есть очень замечательный параметр map_fd который как раз и поможет решить задачу распараллеливание в более привычных терминах, не вдаваясь в специфику resmgr. Совсем упрощенный вариант реализации распределенного по сети кода только средствами spawn и pipes представлен здесь.

Хороший вариант, именно как ещё один вариант - в реальных применениях и одна и другая схемы могут быть предпочтительнее, а может и ещё 3-я и т.д. А "как вариант" потому, что оба решения - в наибольшей мере иллюстрации того, что QNX + QNET - сам по себе "большой кластер", и, в отличие от традиционных OS (особенно макроядерных) - организовать параллельную работу в этой среде на порядки легче.

Теперь по subj, т.е. функциональному различию вариантов (я буду называть "1-й" - свой, исходный, и "2-й" новый):

1. в 1-м варианте sheduler & agent - сопроцессы, без явного соподчинения "родительский-дочерний" (не по запуску, а по тому, как организован pipe-канал) - это не так важно и отчётливо, но все остальные различия вытекают практически из этого.

2. во 2-м варианте связь (в 2-х направлениях) sheduler - agent организована как 2 однонаправленных pipe-канала. Иногда этого достаточно, в общем случае, в реальных задачах - нет. В 1-м варианте таких (двунаправленных) каналов - неограниченно много: каждая devctl() - команда с другим кодом образует новый логический канал: по одному - устанавливаются конфигурационные параметры, по другому - граничные условия и т.д. и т.п.

3. во 2-м варианте последовательности write()-read() со стороны sheduler строго регламентированы (как в любой fork-задаче). Это то, что в коде этой задачи задаётся жёсткой последовательностью чередующихся fgets & fprintf в sheduler:
if (!fgets (buf, sizeof (buf), res)) break;
....
fprintf (cmd, "%d %dn", x, y);
fgets (buf, sizeof (buf), res);

Я же в своём варианте могу делать любые devctl() в любое время - даже в периоды активной счётной работы agent. Это, а также предыдщий п. это - то, что побудило меня в своей иллюстрации для devctl() выделить конфигурационные операции, а за write() - read() оставить основной цикл: задать работу - получить результат. Хотя единообразнее (и в реальной жизни - практичнее) всё нагрузить на devctl(). Т.е. 2-й вариант - он более "синхронный", а 1-й - полностью "асинхронный".

4. может быть, самое главное, что я планировал agent не как подчинённую задачу (запустили-выполнили), а как долговременный сопроцесс: по devctl() передаются конфигурационные данные, а потоком write()- read() (или другими devctl()) - многократно передаются "порции" данных на обработку... и так многократно, корректируя эти "порции" в зависимости от результатов работы и этого хоста, и других... И так они "сосуществуют" ... много-много времени - всё время, пока не выключат систему. Т.е. в моей схеме "обработчик" - это долговременный сопроцесс, его не нужно перезапускать при новом цикле обсчёта. В реальных задачах, напр. из области отждествления отметок в радиолокации (см. текст статьи - мне это ближе и понятнее) - это больше соответствует логике алгоритмов вычислений.

5. обработка ошибок (ненормальных ситуаций): при обмене devctl(), например - я в любое время могу из agent возвратить управление, сообщив, что у меня что-то "не заладилось". С дескрипторным механизмом всё сложнее - если sheduler не ждёт от меня сейчас информации - я никаким образом не смогу ему что-то "прокинуть".

Это можно всё обойти ... но это уже другой разговор.

Ещё маленькое такое "общее" соображение:


Pipes явно недооценены, а точнее их применяемость в QNX (безусловно это resmgr но в понятиях POSIX).

Не нужно забывать, что pipes - не есть "родная" возможность QNX, наоборот - это внешняя, перенесенная из POSIX надстройка над встроенным механизмом сообщений микроядра (тот же механизм - но с несколькими слоями "обёрток"). Т.е. по существу - происходит то же самое, только "под покровом" этих обёрток. Утверждать, что это "более POSIX-совместимо" - не корректно, т.к. в любой другой POSIX-совместимой OS это работать просто не будет. Иногда "прямое" использование обработки сообщений микроядра может оказаться более "открытым" ..., а менеджер ресурсов - это самый простой и стандартизованный (для QNX 6.Х) механизм обработки сообщений микроядра.


Планировщик абсолютно не интеллектуален и просмотрев сеть запускает единственного агента на последнем узле из полученного списка.

Это очень близко к тому, что я описывал в другом месте: http://qnx.org.ru/forum/viewtopic.php?topic=804&forum=14&0 , но там я немного не дошёл до предложенного решения. Вот теперь бы взять, и одно объединить со вторым! Как будет время...


[ Это Сообщение было отредактировано: Olej в 2002-11-19 17:32 ]
Записан
CaptHowdy
Участник
*
Offline Offline

Сообщений: 0


Просмотр профиля WWW
« Ответ #5 : Февраля 25, 2003, 02:22:00 pm »

Может быть это кого-нибудь заинтересует?
http://www.ixbt.com/cpu/clustering.shtml
Интересная статья про построение кластерных систем.
Записан
Страниц: [1]
  Печать  
 
Перейти в: