Несколько соображений по поводу параллельных вычислений в R применительно к «enterprise» задачам

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Параллельные или распределенные вычисления — вещь сама по себе весьма нетривиальная. И среда разработки должна поддерживать, и DS специалист должен обладать навыками проведения параллельных вычислений, да и задача должна быть приведена к разделяемому на части виду, если таковой существует. Но при грамотном подходе можно весьма ускорить решение задачи однопоточным R, если у вас под руками есть хотя бы многоядерный процессор (а он есть сейчас почти у всех), с поправкой на теоретическую границу ускорения, определяемую законом Амдала. Однако, в ряде случаев даже его можно обойти.


Является продолжением предыдущих публикаций.


Типовой подход


Как правило, когда аналитик (DS специалист, разработчик или выберите себе любое подходящее название) пытается ускорить в рамках одного компьютера задачу и начинает двигаться от однопоточного режима к многопоточному, делает он это шаблонным образом. parApply, doreach\%dopar%, etc. Компактно и доходчиво можно поглядеть, например, здесь: «Parallelism in R». 3 шага:


  1. делаем core-1поток,
  2. запускаем с помощью foreach,
  3. собираем ответы и получаем результат.

Для типичных вычислительных задач, занимающих 100% CPU и не требующих передачи большого объема входной информации, это правильный подход. Основной момент, требующий внимания — обеспечить логирование в рамках потоков, чтобы иметь возможность контроля процесса. Без логирования полет пойдет даже без приборов.


В случае «enterprise» задач при их распараллеливании возникает множество дополнительных методологических сложностей, значительно снижающих эффект от приведенного выше прямолинейного подхода:


  • возможная сильная разбалансировка нагрузки на потоки;
  • требования к производительности CPU в рамках отдельной задачи могут иметь рваный характер с наличием только отдельных резких всплесков;
  • каждое отдельное вычисления может требовать значительного объема памяти на вход и выдачу результатов также немалого объема;
  • в рамках отдельной задачи может быть микс между вычислениями, работой с диском и запросом внешних систем.

Это совершенно типичный сценарий, когда в рамках процесса надо получить на вход объемное задание, прочитать данные с диска, забрать большой кусок из БД, поспрашивать внешние системы и дождаться от них ответа (классика — REST API запрос), а потом вернуть в родительский процесс N мегабайт в качестве результата.


Map-reduce по пользователям, локациям, документам,  ip- адресам, датам, … (дополните сами). В самых печальных случаях параллельное исполнение может оказаться более длительным, чем однопоточное. Также могут наблюдаться проблемы с нехваткой памяти. Все пропало? Вовсе нет.


Альтернативный путь


Рассмотрим тезисно способ радикального улучшения ситуации. При этом не забываем, что мы живем в рамках полного зоопарка. Продуктивный контур на *nix, DS ноутбуки на Win*nix\MacOS, а надо, чтобы везде работало единообразно.


  1. Микрозадача: получил на вход пользователя, запросил БД, запросил 2 внешних ИС через REST, скачал и разобрал справочник с диска, провел расчет, сбросил результат на диск\БД. Пользователей, например, 10^6.
  2. Переходим к использованию пакета future и универсального адаптера doFuture.
  3.  Если отдельные задачи таковы, что в рамках отдельных задач процессорное время нужно в малом объеме (ждем ответов сторонних систем), то doFuture позволяет в одну строчку перейти от разбиения по потокам к разбиению по отдельным процессам (можно в *nix в htop поглядеть параметры запуска).
  4. Этих процессов можно создать гораздо больше чем ядер. Никакого клинча не произойдет поскольку отдельные процессы бывают в режиме ожидания большую часть времени. Но надо будет опытным путем подобрать оптимальное число процессов исходя из циклограммы типового процесса обработки.

Результат — исходная задача выполняется в разы быстрее. Ускорение может быть даже больше числа доступных ядер.
Кода нет сознательно, поскольку основная задача публикации — поделиться подходом и отличным семейством пакетов future.


P.S.


Есть еще несколько маленьких нюансов за которыми тоже надо проследить:


  • каждый процесс будет потреблять память, включая получаемые и возвращаемые данные. Увеличение числа процессов кратно увеличит требования по доступной оперативной памяти.
  • doFuture использует «магию» для автоматического определения состава передаваемых в процесс переменных и пакетов, но пускать все на самотек не стоит, лучше проверить.
  • в процессах явное управление gc и явное удаление переменных с помощью rm не помешает.
  • после завершения вычислений вызывайте plan(sequential). Это закроет все процессы и освободит занимаемую ими память.
  • если необходимо передать в процесс большой объем данных рассмотрите возможность использования внешнего хранилища (диск, БД). Не забываем, что дескрипторы передать нельзя, открывать источник надо внутри самого процесса.

Предыдущая публикация — «Бизнес-процессы в enterprise компаниях: домыслы и реальность. Проливаем свет с помощью R».

Источник: https://habr.com/ru/post/462469/


Интересные статьи

Интересные статьи

Распределённые вычисления представляют собой способ решения трудоемких вычислительных задач с использованием нескольких компьютеров, чаще всего объединённых в параллельную вычислительную ...
Предыстория Когда-то у меня возникла необходимость проверять наличие неотправленных сообщений в «1С-Битрикс: Управление сайтом» (далее Битрикс) и получать уведомления об этом. Пробле...
Linux предлагает множество способов разбить окно терминала на несколько мини-экранов, что позволяет обеспечить в определенном смысле «многозадачный» режим работы. Это можно сделать ка...
Устраивать конкурсы в инстаграме сейчас модно. И удобно. Инстаграм предоставляет достаточно обширный API, который позволяет делать практически всё, что может сделать обычный пользователь ручками.
Эта статья для тех, кто собирается открыть интернет-магазин, но еще рассматривает варианты и думает по какому пути пойти, заказать разработку магазина в студии, у фрилансера или выбрать облачный серви...