Комментарии по теме

«Тра­нспо­ртная система SAP для чайников»
Вячеслав Шиболов:
Хорошая метафора с коробками. Наглядная.
«Кло­ни­ро­ва­ние ERP системы. Подробное описание не для ба­зи­сни­ка. Про­до­лже­ние»
Вячеслав Шиболов:
Артем, спасибо за ответ. Но тогда у меня такой вопрос - чем эта статья отличается от статьи на данную тему, если бы вы писали её для базисника?   Извините, может быть вы сочтёте это...
«Python для на­чи­на­ю­щих»
Сергей Громов:
Можно получить ссылку на инструкцию, csv, тетрадки?

База знаний

Ускорение программ через параллельное программирование

715
9

Оглавление

Введение

Концепция

Демонстрационный пример

Код демонстрационной программы Z_PRFC_EXAMPLE

Код функционального модуля Z_TEST_RFC

Практическое применение

Введение

Возникают задачи, в которых требуется выполнить большое количество однотипных операций. При этом, тело операций инкапсулировано, а порядок их выполнения не влияет на конечный результат. Суммарное время выполнения операций может достигать нескольких часов. Примерами таких действий может быть: массовое выполнение BAPI или пакетного ввода. Ускорить такие программы можно через параллельное программирование (pRFC).

Данная статья предназначена для тех, кто понимает принципы работы RFC, умеет работать с синхронными (sRFC), асинхронными (aRFC) и транзакционными RFC (tRFC) и хочет научиться работать с параллельными RFC (pRFC).

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

Концепция

Параллельный RFC работает схожим с aRFC образом, и вызывается с помощью дополнения DESTINATION IN GROUP <имя_группы_серверов>. Группы серверов pRFC определяют максимально возможные ресурсы для выполнения параллельных задач. Группы настраиваются в RZ12 (Рис. 1). Если в качестве имени группы указать DEFAULT или SPACE, то вызов будет происходить на любой из определенных групп, в зависимости от их загруженности.

Рис. 1 – Интерфейс настройки группы серверов в RZ12

Для параллельной обработки в SAP реализован набор функциональных моделей, определенных в группе функций SPBT.

Перед распараллеливанием задач необходимо инициализировать группу серверов, в которой будет выполняться параллельная обработка. Группу можно инициализировать через SPBT_INITIALIZE и только один раз. При повторном вызове SPBT_INITIALIZE будет исключение PBT_ENV_ALREADY_INITIALIZED, если группа уже была инициализирована, или CANT_INIT_DIFFERENT_PBT_GROUPS, если ранее была инициализирована другая группа.

Для определения доступности ресурсов определенной группы можно воспользоваться SPBT_INITIALIZE или SPBT_UPDATE_SRV_RESOURCE_INFO. При успешном выполнении ФМ вернут значения MAX_PBT_WPS и FREE_PBT_WPS, в которых содержатся число максимально доступных и свободных процессов на сервере.

Для определения сервера, на котором будет выполняться задача pRFC, необходимо вызывать SPBT_GET_PP_DESTINATION сразу же после запуска pRFC.

Чтобы исключить конкретный сервер из дальнейшего использования для задач параллельной обработки (например, при исключении COMMUNICATION_FAILURE), необходимо использовать ФМ SPBT_DO_NOT_USE_SERVER.

На Рис.2. представлена диаграмма активности pRFC.

Рис 2. UML диаграмма активности pRFC

Демонстрационный пример

Для демонстрации сделаем тестовую программу и функциональный модуль Z_TEST_RFC. Функциональный модуль будет выполнять какую-нибудь длительную задачу, которую мы будем запускать в параллельном режиме. Пусть это будет возведение числа в квадрат, а для имитации длительной работы сделаем задержку от 3 до 5 секунд.

Допустим, нам нужно выполнить 20 раз данную операцию и возвести первых 20 натуральных чисел в квадрат. На Рис. 3. представлен результат выполнения данной операции при 9-ти свободных процессах. При последовательной обработке на эту же операцию потребовалось бы 80 секунд.

Рис. 3 – Результат работы параллельной обработки

Код демонстрационной программы Z_PRFC_EXAMPLE

 

REPORT z_prfc_example.
TYPES:
  BEGIN OF gts_task,
    task   TYPE c LENGTH 5,
    input  TYPE i,
    result TYPE i,
  END OF gts_task.
DATA gv_tasks TYPE i.
DATA gt_tasks TYPE TABLE OF gts_task.

START-OF-SELECTION.
  PERFORM main.

FORM main.
  DATA lv_time_start TYPE i.
  DATA lv_time_end TYPE i.
  DATA lv_time TYPE i.
  DATA lv_total TYPE i.
  DATA lv_free TYPE i.
  FIELD-SYMBOLS <ls_tasks> TYPE gts_task.

  CALL FUNCTION

Ограниченный доступ

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

Ключевые слова: Разработка / Development , Basis
Функциональная область: Информационные технологии / IT, Basis, ABAP
Ролевое назначение: SAP Консультант / Consultant
Комментарии:

Олег Точенюк (Рейтинг: 11218) 14:28, 31 августа 2020

Чего-то у меня цифры не бьются. Например на установку статуса пусть уходит 1 секунда, и время закрытия 5 часов итого за это время при последовательном закрытии у тебя закрывается 5 * 3600 = 18 000 заказов. После распараллеливания, заказ как зарывался за 1 секунду так и будет закрываться, что его параллельно, что последовательно грузить (бапишке фиолетово она в своем процессе отработает необходимое ей время как ты ее не крути). По твоим словам, теперь это все стало отрабатывать за пару минут, ну пусть это будет 5 минут для ровности. Итого у тебя каждую минуту закрывается сколько? Правильно 3600 / 5 = 720 заказов. Короче я в своей жизни систему с 720 свободными процессами не видел еще, твоя видимо первая будет, ну это чтобы оно таки за пару, точнее 5 минут отработало. В общем если бы была реальная статистика с рабочей системы приведена, было бы чуть интереснее. В свое время когда такое делал я просто привел цифры, чтение 120 000 документов:
 
Паралельно 3 процесса: 11 520 002 милисекунд
Последовательно : 20 632 688 милисекунд
 
А ну и сейчас перформы уже не модно Василий К. придет будет говорить, что это не правильное программирование :-), на классах параллельность выглядит чуток интереснее и красивее в реализации, программа обработки выглядит типа так:
LOOP AT <по каким-то объектам которые надо обработать>.
lcl->read( ).    "Прочитали что надо обработать в процесе
lcl->process( ). "Запустили процесс обработки
lcl->wait( ).    "Ждем если нет свободных процессов, иначе идем на следующий шаг.
ENDLOOP.
16:47, 31 августа 2020

Александр Носов (Рейтинг: 458)

Если 5-8 часов разделить на 30-40 свободных процессов, получится 7-16 минут.
07:47, 01 сентября 2020

Олег Точенюк (Рейтинг: 11218)

Хорошая у вас система, с сорока свободными процессами и еще наверное плюс десятком дополнительных, на других пользователей, пока программа выполняется :-)
08:18, 01 сентября 2020

Александр Носов (Рейтинг: 458)

Ограничение группы серверов не более 25% от общего количества процессов. Всего более 100 процессов. Это разве много?
09:42, 01 сентября 2020

Олег Точенюк (Рейтинг: 11218)

Диалогов? 100 процессов не попадалось если честно, обычно гораздо скромнее. Кстати это какое количество пользователей у вас в системе, если не секрет, что более 100 диалогов открыто?
10:09, 01 сентября 2020

Александр Носов (Рейтинг: 458)

Да, диалогов. А у вас какие значения вернет SPBT_INITIALIZE в продуктиве?
Насчет пользователей не располагаю достоверной информацией.
12:19, 02 сентября 2020

Олег Точенюк (Рейтинг: 11218)

Ну например так:
MAX_PBT_WPS = 24
FREE_PBT_WPS = 22 (на момент запуска)
 
Пользователей скажем так где-то 1100-1200, понятно что активных гораздо меньше. Система S/4
07:30, 03 сентября 2020

Александр Носов (Рейтинг: 458)

Даже если использовать треть диалогов для параллельных задач, можно в 8 раз ускорить некоторые процессы. Для некоторых операций это будет серьезным увеличением.
08:04, 03 сентября 2020

Олег Точенюк (Рейтинг: 11218)

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

Любое воспроизведение запрещено.
Копирайт © «Издательство ООО «Эксперт РП»