OberonCore
https://forum.oberoncore.ru/

Как сделать, чтобы программа работала на обоих процессорах?
https://forum.oberoncore.ru/viewtopic.php?f=31&t=1937
Страница 1 из 3

Автор:  Иван Денисов [ Четверг, 08 Октябрь, 2009 15:23 ]
Заголовок сообщения:  Как сделать, чтобы программа работала на обоих процессорах?

Здравствуйте уважаемые участники форума. Несколько лет стараюсь следить за новостями и разбираться по мере сил со средой BlackBox. Написал программу, которая требует много ресурсов процессора. У меня двуядерный и хотелось бы загружать оба камня вычислениями, а не только один. С потоками и ядром Active BlackBox, пока не разбирался.
Подскажите с чего начать?
Как заставить программу работать на двух процессорах?
Есть ли доступный пример?
Как заложить масштабируемость в программу, на случай, если появится больше процессоров?

Автор:  Илья Ермаков [ Четверг, 08 Октябрь, 2009 15:50 ]
Заголовок сообщения:  Re: Как сделать, чтобы программа работала на обоих процессорах?

Нужно в первую очередь понять характер задач, которые Вы собираетесь решать.

Расскажите, пожалуйста.

Автор:  Иван Денисов [ Четверг, 08 Октябрь, 2009 17:20 ]
Заголовок сообщения:  Re: Как сделать, чтобы программа работала на обоих процессорах?

1. Решаю задачу взаимодействие многих тел. Объект - система тел. Одна процедура вычисляет все силы в системе (тут больше всего операций), вторая сдвигает тела, после того как все силы вычислены, + разные сервисные операции, вывести во вьюшку, записать в файл, записать картинку на диск, отчитаться в Лог.

Этап вычисления сил отлично распараллеливается (в голове пока :) ). Раздаем объект разным процессорам (методам работающим на разных процессорах) и говорим, что один считает первую половину тел системы, второй - вторую. Потом они записывают результат назад в объект и запускается следующая процедура (перемещение). И так далее.

Сейчас я почти в реальном времени считаю 200 заряженных шариков, а необходимо больше. Решил записывать bmp и потом собирать их в avi, чтобы смотреть, что получается, но этот процесс хочется ускорить.

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

Мне бы помог такой инструмент: клоны методов для разных процессоров. Скажем вот такой абстрактный код:

Код:
MODULE GasDinamic;
IMPORT CpuMaster;

TYPE
   Body = RECORD
      f, .... : REAL;
   END;
   System = POINTER TO ARRAY OF Body;

VAR
   gas: System;

PROCEDURE (sys: System) Count (a, b: INTEGER), NEW;
VAR i: INTEGER;
BEGIN
   FOR i:=a TO b-1 DO
      sys[i].body.f := F(sys); (* где F нигде не зависит от sys[*].body.f *)
   END
END Count;

PROCEDURE (sys: System) Step(cpu: INTEGER), NEW;
VAR n,i: INTEGER;
BEGIN
   n:=CpuMaster.HowMuch; (* Определяем сколько процессоров *)
   FOR i:=0 TO n-1 DO
      CpuMaster.Exec(sys.Count(LEN(sys)/n*i,LEN(sys)/n*(i+1)), i); (* выполнить процедуру на i процессоре *)
   END;
   CpuMaster.Wait;    (* теперь ждем пока посчитает каждый свою порцию и продолжаем работу. *)
   ...

END Step;

...

BEGIN
   NEW(gas, 100);
   ...

END GasDinamic.


Как такой CpuMaster написать? Или есть проще решение? Я не специалист в программировании.

Автор:  Илья Ермаков [ Четверг, 08 Октябрь, 2009 17:33 ]
Заголовок сообщения:  Re: Как сделать, чтобы программа работала на обоих процессорах?

Для Вашей задачи однозначно нужно запускать отдельные процессы (отдельные Блэкбоксы). Ведущий ББ раздаёт остальным задания и собирает ответы. Тогда Вы сможете не только несколько процессоров использовать, но и несколько машин.

Наладьте взаимодействие через CommStreams, по протоколу TCP. На одной машине это делается через loopback-адрес localhost (= 127.0.0.1).

В подсистеме Comm есть документация и пример клиента и сервера.

Автор:  Иван Денисов [ Четверг, 08 Октябрь, 2009 17:42 ]
Заголовок сообщения:  Re: Как сделать, чтобы программа работала на обоих процессорах?

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

Автор:  Geniepro [ Четверг, 08 Октябрь, 2009 17:55 ]
Заголовок сообщения:  Re: Как сделать, чтобы программа работала на обоих процессорах?

Илья Ермаков писал(а):
Наладьте взаимодействие через CommStreams, по протоколу TCP. На одной машине это делается через loopback-адрес localhost (= 127.0.0.1).

А не станет ли такая связь бутылочным горлышком? Может лучше общую память использовать (memory-mapped file)?

Автор:  Илья Ермаков [ Четверг, 08 Октябрь, 2009 18:07 ]
Заголовок сообщения:  Re: Как сделать, чтобы программа работала на обоих процессорах?

Нормальный подход - сделать свой модуль с Send - Recv нужных типов. Под него зафигачить CommStreams.

Понадобится оптимизировать - заменить реализацию.

Всегда надо найти способ отложить оптимизации и усложнения на потом. Главное, чтобы оптимизации оставались всегда возможными. (Впрочем, обратное обычно получается вследствие нарушения "разделяй и властвуй". Вот в .NET/Java не разделили ООП и динамическую память - и хоть ап стену убейся...)

Автор:  Info21 [ Четверг, 08 Октябрь, 2009 18:28 ]
Заголовок сообщения:  Re: Как сделать, чтобы программа работала на обоих процессорах?

Илья Ермаков писал(а):
однозначно нужно запускать отдельные процессы (отдельные Блэкбоксы). Ведущий ББ раздаёт остальным задания и собирает ответы.
Ну, кажется, подход, о котором "столько лет говорили большевики", наконец, побеждает.

Автор:  GameHunter [ Четверг, 08 Октябрь, 2009 19:04 ]
Заголовок сообщения:  Re: Как сделать, чтобы программа работала на обоих процессорах?

Может, имеет смысл критические куски программы написать в XDS'е и затем использовать в ББ при помощи DLL? А то ведь возня с несколькими экземплярами ББ, как мне кажется, не лучший путь для оптимизации программы по скорости.

Автор:  Илья Ермаков [ Четверг, 08 Октябрь, 2009 19:22 ]
Заголовок сообщения:  Re: Как сделать, чтобы программа работала на обоих процессорах?

Коллеги, да какая хоть к лешему оптимизация...
Что оптимизировать, если ещё нет не только потребности в оптимизации, но даже самого оптимизируемого объекта??

Автор:  Sergo [ Четверг, 08 Октябрь, 2009 21:48 ]
Заголовок сообщения:  Re: Как сделать, чтобы программа работала на обоих процессорах?

GameHunter писал(а):
Может, имеет смысл критические куски программы написать в XDS'е и затем использовать в ББ при помощи DLL? А то ведь возня с несколькими экземплярами ББ, как мне кажется, не лучший путь для оптимизации программы по скорости.

Кстати, XDS на "числодробительных" задачах может иметь ощутимое преимущество перед BB. Я как-то делал программу для кластерного анализа довольно большого объема данных (обработка одной порции занимала несколько суток). Разница в скорости между XDS и BB была около 2.5 раз.

Автор:  Александр Ильин [ Четверг, 08 Октябрь, 2009 23:00 ]
Заголовок сообщения:  Re: Как сделать, чтобы программа работала на обоих процессорах?

XDS поддерживает multithreading, так что каждый поток выполнения на свой процессор - и вперёд.

Автор:  Info21 [ Пятница, 09 Октябрь, 2009 07:26 ]
Заголовок сообщения:  Re: Как сделать, чтобы программа работала на обоих процессорах?

Sergo писал(а):
... Я как-то делал программу для кластерного анализа довольно большого объема данных (обработка одной порции занимала несколько суток). Разница в скорости между XDS и BB была около 2.5 раз.
Надо бы почаще упоминать о проектах, сделанных на Оберонах, "чтобы народ знал" (С)

Автор:  Иван Денисов [ Пятница, 09 Октябрь, 2009 09:39 ]
Заголовок сообщения:  Re: Как сделать, чтобы программа работала на обоих процессорах?

Думаю сделать модули приема и передачи объекта, а реализацию пока сделать по TCP. возни с ядрами не должно быть, поскольку BlackBox умеет сам тебя запускать, и запуск второго ядра можно включить в программу, и, на сколько я понимаю, дальше операционная система сама разберется какому процессору отдавать операции ядер? С оперативной памятью работать не умею, поэтому эксперименты с общей оперативной памятью пока отложу. Думаю что мой объект не станет узким местом, поскольку он не очень большой порядка нескольких тысяч real, но благодарю за совет, это может пригодится в будущем, и может еще кто будет читать ветку.
Большой плюс что, развитие в сторону работы с сетевым протоколом, дает возможнось масштабирования. При достойной задаче, могут пустить на суперкомпьютер посчитать, а он у нас в универе работает по TCP. Про XDS, у него какая лицензия? Для студентов бесплатная? Если нет, то пока не вариант и как то не в духе BlackBox'а использовать сторонние библиотеки, хотя пришлось прикурить exe'шник ffmpeg, чтобы он картинки собирал в видеофайл.

Автор:  Info21 [ Пятница, 09 Октябрь, 2009 09:51 ]
Заголовок сообщения:  Re: Как сделать, чтобы программа работала на обоих процессорах?

divan писал(а):
При достойной задаче, могут пустить на суперкомпьютер посчитать, а он у нас в универе работает по TCP. Про XDS, у него какая лицензия?
TCP уже давно стандарт на такого рода "суперкомпах" (чего в них такого уж супер, не очень понятно).

XDS бесплатный, только без исходников.

Автор:  Сергей Губанов [ Суббота, 10 Октябрь, 2009 00:25 ]
Заголовок сообщения:  Re: Как сделать, чтобы программа работала на обоих процессорах?

>> в реальном времени считаю 200 заряженных шариков

У меня на втором курсе галактика из 200 звёзд довольно шустро крутилась на 286 компьютере. Лет шесть назад крутилась галактика из 5000 звёзд на Pentium 4 с использованием SSE (правда, чтоб задействовать SSE пришлось на ассемблере писать, ускорение получалось в 8 раз чем без SSE). Поэтому возникает вопрос. Вам сколько тел надо обсчитывать? Если меньше пяти тысяч, то может Вам на самом деле распараллеливания не надо, а просто нужно подумать над алгоритмом как следует?

Автор:  Александр Ильин [ Суббота, 10 Октябрь, 2009 06:20 ]
Заголовок сообщения:  Re: Как сделать, чтобы программа работала на обоих процессорах?

divan писал(а):
как то не в духе BlackBox'а использовать сторонние библиотеки
Ничего себе заявленьице. : ) Стандартные контролы, окна и меню уже не считаются? : ) Они из виндовой библиотеки взяты, а не на ББ написаны.
А если поддержку разных форматов изображений делать - тоже самому писать? Или лучше FreeImage.dll задействовать?
Свой код иметь, конечно, лучше во многих случаях, но не во всех.

Автор:  Иван Денисов [ Воскресенье, 25 Октябрь, 2009 12:23 ]
Заголовок сообщения:  Re: Как сделать, чтобы программа работала на обоих процессорах?

По TCP отправлять можно только BYTES, как я понял, значит REAL нужно в BYTES преобразовывать. Подскажите, как это сделать? Ведь один REAL занимает 4 BYTES.

Автор:  Info21 [ Воскресенье, 25 Октябрь, 2009 14:54 ]
Заголовок сообщения:  Re: Как сделать, чтобы программа работала на обоих процессорах?

divan писал(а):
Ведь один REAL занимает 4 BYTES.
8.

Смотрите исходник модуля Stores:
PROCEDURE (VAR wr: Writer) WriteReal* (x: REAL), NEW;

Сделайте аналог Stores.Writer|Reader над TCP.

(Давно уж пора сделать бы ...)

Автор:  Сергей Губанов [ Понедельник, 26 Октябрь, 2009 10:57 ]
Заголовок сообщения:  Re: Как сделать, чтобы программа работала на обоих процессорах?

Не надо над TCP делать read/write мапперы навроде Stores.Reader/Writer. Это просто не эффективно, например, если выполнено два вызова WriteByte, то значит по сети надо переслать 1 байт, а потом переслать ещё 1 байт? Нет, здесь паттерн carrier-rider-mapper не применим. Сеть - это не carrier. По сети надо передавать пакеты сообщений (то есть даже не по одному сообщению, а по целой пачке сообщений за раз). Потоковый протокол TCP был изобретён по ошибке. Сейчас уже это поняли и от него начинают отказываются в пользу других протоколов согласно которым по сети течёт не поток байтов, а едут достаточно большого размера сообщения (что-то вроде UDP, но только с гарантированной доставкой, и сообщения произвольного размера).

Страница 1 из 3 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/