gifts2017

Многопоточность как способ ускорения некоторых процедур

Опубликовал Алексей Бочков (Aleksey.Bochkov) в раздел Программирование - Практика программирования

Платформа 1С:Предприятие 8 обладает необходимыми инструментами для обеспечения многопоточности, но на практике про эти инструменты незаслуженно забывают.

Конечно, многопоточность – это не панацея, но это хороший способ для:

1)      уменьшения длительности выполнения длительных процедур (в некоторых ситуациях - на порядки!);

2)      повышения утилизации ресурсов оборудования.

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

Пара примеров:

1)      Существует несколько сотен магазинов, работающих на самописном ПО, и единая база в головной компании, куда ежедневно выгружаются транзакции по продажам. Загрузка инициируется пользователем по кнопке и занимает длительное время, т.к. магазинов много и транзакций приличное количество, а обработка пакетов данных идет последовательно.

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

В этом примере ускорение может быть не очень большим, т.к. формирование документов занимает меньше времени, нежели их проведение.

2)      Существует большая база данных с транзакциями по продажам магазинов (из предыдущего примере) и есть необходимость периодически выгружать эти данные в стороннюю BI-систему средствами 1С. Выгрузка инициируется пользователем и занимает длительное время, т.к. системе нужно получить из базы данных миллионы строк и выгрузить их в промежуточную базу для BI. Во время выгрузки данных оборудование загружено несущественно.

В этой ситуации можно было бы распараллелить выгрузку данных – одновременно выгружать данные по разным магазинам. Это существенно ускорит процесс и позволит в полной мере ощутить эффект от мощного железа.

Инструменты встроенного языка для выполнения многопоточной процедуры.

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

Пример кода для второго случая (выгрузка большого массива данных порциями):

1)      Процедура, инициирующая многопоточное выполнение кода:

 Процедура КнопкаВыполнитьНажатие(Кнопка)

   
//указывает число потоков, которые будут запущены одновременно
   
ЧислоПараллельныхПотоков = 10;

   
МассивЗаданий = Новый Массив;

   
Запрос = Новый Запрос(
   
"ВЫБРАТЬ РАЗЛИЧНЫЕ
    |    ПартииТоваровНаСкладах.Склад
    |ИЗ
    |    РегистрНакопления.ПартииТоваровНаСкладах КАК ПартииТоваровНаСкладах
    |ГДЕ
    |    ПартииТоваровНаСкладах.Период МЕЖДУ &Дата1 И &Дата2"
);
   
Запрос.УстановитьПараметр("Дата1", ДатаНачала);
   
Запрос.УстановитьПараметр("Дата2", ДатаОкончания);

   
Результат = Запрос.Выполнить().Выгрузить();

    Для каждого
Стр из Результат Цикл

       
МассивПараметров = Новый Массив;
       
МассивПараметров.Добавить(ДатаНачала);
       
МассивПараметров.Добавить(ДатаОкончания);
       
МассивПараметров.Добавить(Стр.Склад);

       
Задание = ФоновыеЗадания.Выполнить("ВыгрузкаДанныхНаСервере.ВыгрузитьДанныеПоПартиям", МассивПараметров);

       
МассивЗаданий.Добавить(Задание);

        Если
МассивЗаданий.Количество() >= ЧислоПараллельныхПотоков Тогда
            Попытка
               
ФоновыеЗадания.ОжидатьЗавершения(МассивЗаданий);
            Исключение
            КонецПопытки;
           
МассивЗаданий.Очистить();
        КонецЕсли;

    КонецЦикла;

    Если
МассивЗаданий.Количество() > 0 Тогда
        Попытка
           
ФоновыеЗадания.ОжидатьЗавершения(МассивЗаданий);
        Исключение
        КонецПопытки;
       
МассивЗаданий.Очистить();
    КонецЕсли;

   
Сообщить("Время выполнения процедуры - " + (ТекущаяДата() - ВремяНачала) + " с.");

КонецПроцедуры

2)      Процедура, которую непосредственно выполняет фоновое задание (основная логика):

 Общий модуль «ВыгрузкаДанныхНаСервере», выполняемый на сервере:

Процедура ВыгрузитьДанныеПоПартиям(ДатаНачала, ДатаОкончания, Склад) Экспорт

   
Запрос = Новый Запрос(
   
"ВЫБРАТЬ
    |    *
    |ИЗ
    |    РегистрНакопления.ПартииТоваровНаСкладах КАК ПартииТоваровНаСкладах
    |ГДЕ
    |    ПартииТоваровНаСкладах.Период МЕЖДУ &Дата1 И &Дата2
    |    И ПартииТоваровНаСкладах.Склад = &Склад"
);

   
Запрос.УстановитьПараметр("Дата1", ДатаНачала);
   
Запрос.УстановитьПараметр("Дата2", ДатаОкончания);
   
Запрос.УстановитьПараметр("Склад", Склад);

   
Результат = Запрос.Выполнить().Выгрузить();

    Для каждого
Стр из Результат Цикл
       
//Что-то делаем с данными
   
КонецЦикла;

КонецПроцедуры

 При этом случает учесть, что к выбору числа параллельных заданий нужно отнестись ответственно – если запустить их даже несколько десятков, то велика вероятность «повесить» и сервер приложений, и сервер СУБД.


См. также

Подписаться Добавить вознаграждение

Комментарии

1. Станислав Раташнюк (stanru1) 09.04.13 23:14
А где гарантии, что несколько фоновых задании распараллелятся по нескольким ядрам? Тут, видимо, надо подумать и на тему создания рабочих процессов (т.к. фоновые задания запускаются в своих сеансах)?
redwonder87; +1 Ответить 1
2. Алексей Бочков (Aleksey.Bochkov) 09.04.13 23:30
(1) - фоновые задания однозначно параллелятся на разные ядра. Сервер 1С - это многопоточное приложение, которое способно задействовать все ядра даже при одном рабочем процессе.
3. Станислав Раташнюк (stanru1) 10.04.13 00:17
(2) не поленился проверить. да, вы правы - загружает все доступные ядра при росте нагрузки.
4. Юрий Осипов (yuraos) 10.04.13 06:05
В целом плюс за оригинальную идею
...
но все-таки это "фоновые задания",
а не "многопоточность выполнения" в том смысле,
котором она трактуется в курсах по теории операционных систем.
---
более коррекно было бы говорить о использовании
фоновых заданий для выполнения параллельной обработки данных.
5. Андрей (redwonder87) 10.04.13 06:37
Очень хорошая идея, существенно позволяет развить направление собственных разработок на базе 1С. Спасибо за идею и наглядный пример.
6. soba (soba) 10.04.13 06:49
В файловом варианте, надо полагать, точно так же реагирует ? Или применимо только к Клиент-серверному варианту?
Для меня актуально для формирования и рассылки отчетов клиентам по итогам периода, а проверить-то и некогда в ближайшие дни
7. Serj (Serj1C) 10.04.13 07:25
(6) в файловой с фоновыми заданиями облом
8. Алексей Бочков (Aleksey.Bochkov) 10.04.13 07:33
(4) - если смотреть определение "многопоточности" в википедии, то вы правы - это более сложное понятие и не совсем тут применимо, но мне показалось, что этот термин допустим, т.к "многозадачность", более подходящая тут по смыслу, для большинства будет не так очевидна. Опять же - сугубо ИМХО.
9. Тимур Багаутдинов (Timur_Bagautdinov) 10.04.13 08:01
(0) А какие-нибудь замеры производительности делались? Какова величина ускорения и эффективности?

Имеет ли смысл этим заниматься, если прирост не столь существенен
10. Сергей Кучеров (СергейКа) 10.04.13 08:07
В целом мы давненько это используем, но тут есть пара условий:
1) конфигурация должна быть самописная или переписанная типовая, без изменения самой конфигурации не сделаешь;
2) клиент-серверный вариант;
3) с фоновыми иногда проблемы в платформе бывают, так что нужен дополнительный контроль.
11. Алексей Бочков (Aleksey.Bochkov) 10.04.13 08:23
(9) - в этом уравнении много переменных, поэтому конкретные замеры приводить бесполезно.
Все зависит от:
1) характера операции, которую "параллелят"
2) доли параллельных операций в общем объеме (как в моем первом примере, когда только часть процедуры выполняется параллельно)
3) мощности железа - грубо говоря, однопроцессорный сервер "потянет" 10 одновременных фоновых заданий, а четырехпроцессорный - 50-100. Замеры будут совсем разные.
В общем случае, можно добиться уменьшения длительности выполнения операции кратно числу параллельных фоновых заданий.
KroVladS; ftm; w-divin; +3 1 Ответить 1
12. Тимур Багаутдинов (Timur_Bagautdinov) 10.04.13 10:14
(11) Как это бесполезно замерять?

Ведь что-то оптимизируя, нужно понимать и видеть, какой от этого выхлоп.

1. Узнать, какое ускорение принес метод параллельной обработки данных. На повышение производительности влияет много факторов. Ведь получив прирост 5-10%, дополнительный повод для подробного исследования алгоритма.

2. Также следует знать эффективность. Параллельный алгоритм может давать большое ускорение, но использовать для этого множество процессов неэффективно. Грубо говоря добавили 100 процессоров, а ускорение вышло всего в 2 раза.

3. Понимать насколько масштабируемо решение. Например, 4 фоновых процесса работают на ура, а 8 уже нет, к примеру, не хватает уже оперативной памяти.

Итого, замер - обратная связь от наших действий.

Вот у Вас приведено две конкретных задачи. Интересно узнать, как в вашем случае такой подход дает выхлоп.
Если все круто, близкое к линейному ускорению, то это повод поближе познакомиться с задачей и перенять опыт.

В любой распространенной библиотеке для высокопроизводительных вычислений MPI, OpenMP, TBB и т.п. есть демо примеры, есть опыт сообщества - везде рисуют графики, приводят замеры, делятся опытом.
13. Олег Филиппов (comol) 10.04.13 11:24
"бородатый баян" конечно, но людям, пожалуй, полезный...
14. Олег Филиппов (comol) 10.04.13 11:29
(2) Aleksey.Bochkov, Не совсем верно конечно... нити по ядрам распараллеливает Windows, а не сервер 1С. Сервер 1С их только создаёт. Самое главное что сервер 1С создаёт поток только для сеанса (или для соединения), следовательно если у вас будет одно соединение, которое будет выполнять всю "тяжелую работу" все ядра сервер 1С не загрузит. До многопоточности, которая существует в нормальных серверах СУБД, серверу 1С конечно ещё далеко...
Yashazz; awk; +2 Ответить 3
15. Ak A (frc) 10.04.13 11:36
(8) Aleksey.Bochkov,
Наиболее эффективно организовать многопоточность можно с помощью Фоновых заданий (не путать с регламентными заданиями).

Фоновые и регламентные - одно и то же:
одни запускает сервер, вторые - тоже сервер, но по отмашке пользователя.
Но все выполняются в порядке очереди с основным расчетом.
Где тут автор увидел многопоточность - непонятно...
16. Ak A (frc) 10.04.13 11:37
При этом случает учесть, что к выбору числа параллельных заданий нужно отнестись ответственно – если запустить их даже несколько десятков, то велика вероятность «повесить» и сервер приложений, и сервер СУБД.

Авторо, покурите на досуге собственную фразу - почему нельзя, и где тут многопоточность вдруг нашлась.
17. Ak A (frc) 10.04.13 11:53
(14) comol,
тоже не верно.
1С ничего не распараллеливает. ОС - тем более.
Параллельные вычисления - это одновременное выполнение каких-то операций.
ОС может "давать ход" нескольким процессам одновременно (загружая несколько ядер, используя HT и т.д.). 1С - ничего это не может. Даже распараллелить собственные вычисления.
18. Алексей Бочков (Aleksey.Bochkov) 10.04.13 11:54
(12) - не нужно искажать фразы :).
Я писал про бесполезность приведения (публикации) результатов, а не бесполезность самих замеров.
Ну сделаю я замеры на своем железе и получу прирост в 100 раз, а вы повторите у себя и получите 80-кратный прирост - результат получается не чистым.

Фразы "В общем случае, можно добиться уменьшения длительности выполнения операции кратно числу параллельных фоновых заданий." тут вполне достаточно и это соответствует общему подходу 1С - от фирмы 1С вы не найдете публикаций абсолютных значений производительности в конкретных условиях.
Я лишь привел инструмент. Детальный анализ его эффективности - это уже задача разработчика в конкретной ситуации. Хотя могу и я сделать, не за бесплатно, конечно :).
19. Алексей Бочков (Aleksey.Bochkov) 10.04.13 11:56
(13) - насчет баяна не согласен :)
Вроде все знают о фоновых заданиях, а о том, что их так можно использовать - не все догадываются.
(14) - в моей формулировке "Сервер 1С - это многопоточное приложение, которое способно задействовать все ядра даже при одном рабочем процессе." нет уточнения входных параметров, поэтому в общем случае она верна. Тем более, что это почти дословно слова Сергея Нуралиева. Ему, как разработчику, виднее.
20. Алексей Бочков (Aleksey.Bochkov) 10.04.13 11:58
(15) - советую почитать желтые книжки. Фоновые и регламентные задания - это разные вещи.
Если простыми словами:
Фоновое задание - выполнение кода в отдельной сессии.
Регламентное задание - комбинация расписания и фонового задания.
21. Алексей Бочков (Aleksey.Bochkov) 10.04.13 12:00
(16) - на досуге советую потренировать восприятие чужих текстов и постараться меньше хамить без приведения здравой критики :).
Предупреждение "При этом случает учесть, что к выбору числа параллельных заданий нужно отнестись ответственно – если запустить их даже несколько десятков, то велика вероятность «повесить» и сервер приложений, и сервер СУБД." достаточно простое, понятное и в тему.
chernoff; comol; +2 Ответить
22. Станислав Раташнюк (stanru1) 10.04.13 12:12
(14) жаль, я вчера не заскриншотил, 1с (или Windows) чудесно загрузила все 32 ядра при увеличении количества фоновых заданий.

(12) Timur_Bagautdinov, не поленился, вот результаты теста:



от 1 до 10 одновременно запущенных фоновых заданий.
каждое задание 10 млн раз занималось делением случайных чисел
среднее время выполнения каждого задания в мс
23. Олег Филиппов (comol) 10.04.13 12:13
(17) frc, давайте погрузимся дальше - тоже не верно. число одновременно выполняемых операций процессором определяется числом возможных очередей команд. Команды в очередь помещает даже не процесс и не системное ПО, что-то распарралеливает только сам процессор. так? А если ещё глубже могёте? :))))
24. Олег Филиппов (comol) 10.04.13 12:16
(19) Aleksey.Bochkov, Фраза то верна, но такое определение очень часто вызывает недопонимание "почему у меня при расчете себестоимости только одно ядро загружено, где ваше многопоточное приложение?"...
25. Дмитрий Елисеев (w-divin) 10.04.13 12:19
(22) Правильнее было бы показывать не среднее время каждого задания, а общее время выполнения всех заданий в вариациях очередь по 1, очередь по 2, очередь по 3... все 10 одновременно
26. Тимур Багаутдинов (Timur_Bagautdinov) 10.04.13 12:36
(18) А что, у "1С" по этому поводу публикации есть? Можно ссылочки на них?

Не хотите давать результатов, что ж, Ваша статья голословна.

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

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

(22) А что должен показать данный график? В чем его смысл?
27. Ak A (frc) 10.04.13 13:33
(23) comol,
совершенно неверно путать очередность выполнения команд процессора, распараллеливание процессов в ОС и параллельные вычисления.
Первое - делает процессор ко всем без исключения командам, поступающим к нему - будь то запись файла или какой-то расчет в 1С. Предугадал команду, совпало - "распараллелил", нет - по очереди.
Второе - делает ОС по отношению к своим процессам: может икнуть какой-то процексс на другое ядро там и т.д. - кидает. Нет (по разным своим системным причинам - и отнюдь не зависящим от параллельности процессов) - идут на выполнение друг за другом.
А третье - третье не реализовано в 1С.

(20) Aleksey.Bochkov,
Фоновое задание - выполнение кода в отдельной сессии.
Регламентное задание - комбинация расписания и фонового задания.

т.е. расписание - это превращает фоновое задание в "нечто другое"? :)
28. Станислав Раташнюк (stanru1) 10.04.13 13:37
(25) w-divin, вот время выполнения "пакетов" фоновых заданий



(26) Timur_Bagautdinov,
график показывает, что происходит реальное "распараллеливание" заданий. То есть идея, выдвинутая автором публикации, работает и имеет право на жизнь.
29. Олег Филиппов (comol) 10.04.13 13:46
(27) frc, Ух ты... и это вы тоже знаете? :))) Я впечатлен вашими познаниями! Вы тоже прочитали "методичку МГТУ имени Баумана" за 3 курс? :))) А какие вам известны парадигмы параллельного программирования? Давайте что-нибудь ещё обсудим и померяемся? :)
30. Андрей Акулов (verter.me) 10.04.13 16:09
Отличная статья Алексей.
31. Роман Мишкин (smilejka) 10.04.13 16:31
(28) stanru1,
Непонятно по графику:
получается чем больше потоков, тем больше время выполнения операции? Тогда это никакое не ускорение процедур...
32. Юрий Осипов (yuraos) 10.04.13 17:25
(20) Aleksey.Bochkov,
это как раз тот случай,
когда в "желтых" книжках
(как и в библии или в полном собрании сочинений ВИЛ-а)
действительно можно вычитать что-нибудь полезное.
33. Юрий Осипов (yuraos) 10.04.13 17:36
(27) frc,
я бы сказал так:
регламентное задание -
это "расписание" запускающее фоновые задания, выполняющие код
(фоновых заданий может быть к стати много).


не расписание "делает" фоновое задание регламентным,
но фактически расписание и само есть регламентное задание.
34. Юрий Осипов (yuraos) 10.04.13 17:41
(7) Serj1C,
я бы сказал не облом ... а хуже - "ГЕММОРОЙ".

В принципе можно запускать фоновые задания в специально
отведенном для этого соединении с файловой базой.

Только машинка должна быть помощьней и сетка пошустрей,
чтобы добиться того, что здесь обсуждается.
35. Станислав Раташнюк (stanru1) 10.04.13 18:29
(31) smilejka, график как раз показывает, что одновременно выполняемые 10 заданий будут выполнятся (все! общее время выполнения) лишь в полтора раза дольше, чем 1.
Надо учитывать, что у меня синтетика, а реальные задачи могут показать худшие результаты. Однако это будет все равно быстрее, чем последовательное выполнение.
С исключениями, о которых писал в публикации автор.
36. Антонио (Fragster) 10.04.13 19:53
У меня есть многопоточный тест производительности: http://infostart.ru/public/173394/
показывает потенциальное количество пользователей или же выигрыш от распарралеливания, смотря как интерпретировать. На нормальном железе суммарная производительность в многопоточном режиме в десятки раз больше однопоточного.
37. Alex Steiner (OrsoBear) 11.04.13 09:04
Да, тоже недавно начал пользоваться этим методом.
Настало время, когда параллельно несколькими делами надо заниматься.
38. Яков Коган (Yashazz) 11.04.13 10:55
Для меня это баян старинный. К тому же, и на ИС подобное уже вроде было. Напрашивающееся же решение...
А вот пример мне не нравится, я б в более общем виде представил саму концепцию, безо всякой конкретики в виде разных там складов и партий.

Если я правильно понял в своё время Гилёва, то сервер 1С ничего не распараллеливает по ядрам, и будь хоть стоядерный процессор, важна его частота, а не количество ядер, потому что 1С их не задействует оптимально.
39. Vladimir K (KroVladS) 11.04.13 11:41
(0)
Очень интересный механизм.
У меня как раз есть задача для его применения. Надо будет обязательно попробовать.

Спасибо за статью.
40. Станислав Раташнюк (stanru1) 11.04.13 13:56
(38) как объяснить тогда, что ядра загружаются по мере роста количества фоновых заданий?
рабочий процесс один. Изначально загружены 1-2 ядра. Начинаем запускать фоновые задания. Под конец эксперимента загрузились все ядра.
41. AlexPotemkin123 (_HakerAlex_) 11.04.13 15:31
Пример в принципе стандартный, и во многих конфигурациях стандартных используется, но на самом деле самое узкое место как раз при проведении, то есть другими словами повиснем на транзакциях. И ядра нам не помогут, нужно делать управляемые блокировки. А за статью спасибо...
42. Антонио (Fragster) 11.04.13 16:00
(41) AlexPotemkin123, ну, например, долгие расчеты, восстановление последовательности и прочее - вполне себе параллелится. Проведение одного документа параллелить, конечно, смысла мало.
43. Vladimir K (KroVladS) 11.04.13 20:28
Проверил на реальной задаче.
Есть надстройка над УТ 10.3 для работы с КПК "Агент+".

Типовая задача выгрузка данных всем Агентам.
Я ограничил выгрузку первыми 10 агентами, вот результат:

Обычная выгрузка. БЕЗ фонового задания.
Общая выгрузка. Время выгрузки 262 с

Фоновое задание 1 поток.
Общая выгрузка. Время выгрузки 223 с

Фоновое задание 2 потока.
Общая выгрузка. Время выгрузки 157 с

Фоновое задание 5 потоков.
Общая выгрузка. Время выгрузки 73 с

Фоновое задание 10 потоков.
Завершаеться с ошибкой, но создались файлы для 7 агентов:
Ошибка при вызове метода контекста (ОжидатьЗавершения): Выполнение одного или нескольких заданий завершилось с ошибкой
на строке:
ФоновыеЗадания.ОжидатьЗавершения(МассивЗаданий);

Я думаю и без красивых графиков преимущества очевидны.
Данные с тестового сервера, кроме меня в этой базе ни кто не работает. Пока непонятно как будет вести себя база и насколько комфортно работать остальным пользователям.
44. Антонио (Fragster) 11.04.13 20:51
(43) KroVladS, интересно, с чем связано то, что 1 фоновое задание выполняется быстрее, чем просто в предприятии?
45. Гость 12.04.13 06:38
Фоновое задание всегда выполняется параллельно работе клиентов, а это уже означает значит выполнение в отдельном потоке. В идеале оно выполняется параллельно на отдельных ядрах, а не тормозит клиентское подключение отрывая от него куски процессорного времени.

По этой же причине в файловом варианте для регламентных заданий требуется отдельный процесс на клиенте - нет сервера 1С и некому выполнять задания в отдельном потоке, кроме как другому процессу на клиенте.

То что сервер 1С не может создать дополнительный поток для одного клиента как раз приводит к тому что многопоточность нельзя реализовать в 1С стандартными для других языков программирования средствами. Нет класса Thread. Это ограничение продиктовано скорее прикладным назначением клиентских подключений, нежели непродуманностью платформы и желанием ее разработчиков облегчить себе жизнь :)

Но способность самого сервера 1С создавать потоки для фоновых заданий и запускать их параллельно от выполнения "клиентского" кода от этого никуда не исчезает.
46. Vladimir K (KroVladS) 12.04.13 09:43
(43) KroVladS,
Фоновое задание выполняется на сервере, что по логике уже быстрее чем на клиенте.

Домыслы:
1. задание по выгрузке находиться в модуле обработки, которая при инициализации на клиенте подключает несколько COMобьектов, на сервере я их не подключаю, т.к. при выгрузке они не используються.
2. При выполнении на клиенте выводиться лог работы выгрузки, примерно так:
#Если Клиент Тогда
	Состояние("Выполенение операции №1...");
	СтартОперации=ТекущаяДата();
#КонецЕсли

ВыполнитьОперацию1();
			      	
#Если Клиент Тогда											   
	СтопОперации = ТекущаяДата();
	Сообщить("Выполенение операции №1 ="+(СтопОперации - СтартОперации));
#КонецЕсли
...Показать Скрыть
по 20 раз для каждого агента.
на сервере они соответственно не выполняются,
3. Запуск фонового задания происходит из Привилегированного модуля, может не происходит проверка на права и РЛСы.
47. Vladimir K (KroVladS) 12.04.13 10:07
Сделал график к данным из (43).
Прикрепленные файлы:
48. nicolas eliseev (nicxxx) 12.04.13 13:26
присоединяюсь к (15). в файловом варианте распараллеливания не происходит, все задания из массива выполняются последовательно.
49. Станислав Раташнюк (stanru1) 12.04.13 14:42
(48) использовать файловый вариант и фоновые задания на мой взгляд в принципе извращение. только если по-иному уж совсем никак нельзя.
50. nicolas eliseev (nicxxx) 12.04.13 19:02
ситуация так сложилась, что сервер использовать не получится. была надежда, что если запустить несколько сеансов с обработкой ожидания, то массив заданий будет выполняться параллельно, но не оправдалась
51. Vladimir K (KroVladS) 12.04.13 19:04
Добавил проверку на выполнение фонового задания, если задание завершилось неудачно перезапускаю 5 раз.
Добавил в рабочую базу, 60 заданий в 60 потоков, из них 4-5 заданий перезапускаются из-за блокировок.

Итог ПОЛТОРЫ минуты вместо получаса.

Может для кого то это и "бородатый баян", но мне эта публикация очень помогла.
Спасибо.
Puk2; Aleksey.Bochkov; +2 Ответить 1
52. Антонио (Fragster) 12.04.13 19:25
(51) KroVladS, Количество фоновых можно подобрать тестом из (36). обычно больше 8-16 смысла не имеет, а наибольший прирост - так вообще на 4-8
53. Vladimir K (KroVladS) 12.04.13 19:44
(52) Fragster,
Экспериментировал с разным количеством потоков.
Проблема в том, что не все задания равнозначны, разброс по времени от 20 сек. до 60 сек. Блокировки начинаются примерно от 10 потоков, причём проблемы именно с долгими заданиями.
Можно запустить в 8 потоков, но это в три раза дольше, при этом нет гарантии что оно всегда будет выполняться без блокировок.
Я решил сделать каждое задание в свой поток, но отслеживать и перезапускать отвалившиеся задания.
54. Антонио (Fragster) 12.04.13 20:15
(53) KroVladS, нужно сделать диспетчер очередей и как только одно заканчивается - запускать новое. я одно время пытался заморочится внешним (из-за того, что у 1с нету функции паузы, которая бы не грузила процессор), чтобы не перезапускать задания (которые сами по себе несколько секунд могут запускаться), а вместо этого сделать постоянный "пул заданий", которому бы просто "независимые атомы" из очереди можно было бы запихивать, но не взлетело, к сожалению.
55. Юрий Осипов (yuraos) 12.04.13 20:50
(54) Fragster,


...(из-за того, что у 1с нету функции паузы, которая бы не грузила процессор)...


тут есть народное средство от StepByStep
для имитации паузы в 1С:
// Функция задержки выполнения процесса.
//
&НаКлиентеНаСервереБезКонтекста
Процедура ЗадержкаВВыполнении(ВремяОжидания)
   Попытка
      xPing = "ping -n 1 -w "+Формат(1000*ВремяОжидания, "ЧГ=0")+" 127.255.255.255";
      WshShell = Новый COMОбъект("WScript.Shell");
      WshShell.Run(xPing, 0, -1);
   Исключение
   КонецПопытки;  
КонецПроцедуры
...Показать Скрыть


его не пробывал ???
(конечно если сервер под виндой )
56. Антонио (Fragster) 12.04.13 22:14
(55) yuraos, про этот способ я знаю, сам его использую, причем несколько более кроссплатформенным образом (опять же в (36), работает начиная с 8.2.14):
Процедура Пауза() Экспорт
	Инфо = Новый СистемнаяИнформация();
	Если 
		Инфо.ТипПлатформы = ТипПлатформы.Windows_x86 ИЛИ 
		Инфо.ТипПлатформы = ТипПлатформы.Windows_x86_64
	Тогда
		ЗапуститьПриложение("ping -n 2 127.0.0.1", , Истина); // windows
	Иначе
		ЗапуститьПриложение("ping -c 2 127.0.0.1", , Истина); // linux
	КонецЕсли;
КонецПроцедуры
...Показать Скрыть


однако для очередей, о которых я говорю 1 секунда - слишком много, вот если бы 1/50 секунды, тогда да, имело бы смысл не выключать фоновые задания, но такое только с помощью ВК или другого внешнего приспособления может быть достигнуто (причем менее стандартного, чем пинг).
57. IR IR (Artemuch2) 13.04.13 17:15
Да идея ничего так. Надо будет попробовать
58. AlexBar (AlexBar) 14.04.13 18:07
Я использую данную технологию уже более 2-х лет. Ранее я уже несколько раз писал об этом на ИС. Автор молодец, что оформил саму технологию в виде публикации.
Я считаю что споры о том что есть фоновое задание, что есть регламентное задание абсолютно не уместны. Так же как и придирки к понятию "многопоточности". Для того, чтобы построить многопоточность, нужно вообще понять как распараллелить сам код и контекст его выполнения. Все фоновые задания, не важно чем они запускаются (командой пользователя или регламентным заданием), выполняются в параллельном режиме (клиент-серверный режим), а это значит что любая операция, которую можно разложить на несколько параллельных независимых операций, выполнится на порядки быстрее, пусть не в N количества операций, но быстрее в разы однозначно.
Количество параллельных заданий так же является спорным параметром, так как все зависит от того, как сильно код, исполняемый заданием, грузит процессор(ы). Если в задании производить мелкие математические операции, то можно запустить и 1000 заданий параллельно, процессор ничего не "почувствует". Если в задании производить чтение/запись данных, выполнение запросов к ИБ, то нагрузка будет увеличиваться по вполне понятным причинам.
Я не ограничиваюсь каким-либо числом заданий, а использую функцию, которая определяет общую загрузку процессоров сервера. Это дает мне возможность определить не только работоспособность n-числа фоновых заданий, но и комфортность работы пользователей. т.е. создаваемые фоновые задания не должны тормозить работу пользователей, создавая избыточную загрузку ресурсов сервера. Мои методы создают такое количество заданий, пока загрузка процессоров не достигнет 70%. Сколько при этом создастся фоновых заданий - совершенно не важно. Возможно что код такой тяжелый, что и одно задание загрузит сервер под завязку, тогда и никакое "распараллеливание" не поможет, так как 2 подобных задания параллельно будут выполнятся столько же времени сколько и последовательно, если не дольше.
Для контроля выполнения заданий дополнительно использую регистр сведений. К примеру требуется разузловать 100 строк таблицы Продукция. Вполне понятно что эту процедуру можно производить параллельно, вот только результаты нужно сложить. Запускаю в цикле фоновые задания и создаю записи в РС. Там, где задание отработало, оно устанавливает признак в своей строке РС и записывает туда результат. Когда все задания отработают, собираем из РС результат. Не претендую на исключительность, можно реализовать и иначе, просто делюсь опытом.
avto1c; PONOM; DitriX; KroVladS; +4 Ответить 1
59. Сергей Бушмакин (relanium86) 15.04.13 14:42
Странно у меня получилось следущиее
Время выполнения процедуры - 102 с. с фонововыми
Время выполнения процедуры - 7 с. без фоновых

Ниже код
    //указывает число потоков, которые будут запущены одновременно
	//ЧислоПараллельныхПотоков = 10;

	//МассивЗаданий = Новый Массив;
    ВремяНачала = ТекущаяДата();

    Для а = 1 По 50 Цикл
		ГСЧ = Новый ГенераторСлучайныхЧисел;		
		Параметр = а*ГСЧ.СлучайноеЧисло(0, 10000);
		//МассивПараметров = Новый Массив;
		//МассивПараметров.Добавить(100000);
		//МассивПараметров.Добавить(Параметр);
        СерверныйМодуль.РасчитатьЧисло(100000, Параметр);
		//Задание = ФоновыеЗадания.Выполнить("СерверныйМодуль.РасчитатьЧисло", МассивПараметров);

		//МассивЗаданий.Добавить(Задание);

		//Если МассивЗаданий.Количество() >= ЧислоПараллельныхПотоков Тогда
		//	Попытка
		//		ФоновыеЗадания.ОжидатьЗавершения(МассивЗаданий);
		//	Исключение
		//	КонецПопытки;
		//	МассивЗаданий.Очистить();
		//КонецЕсли;

    КонецЦикла;

	//Если МассивЗаданий.Количество() > 0 Тогда
	//	Попытка
	//		ФоновыеЗадания.ОжидатьЗавершения(МассивЗаданий);
	//	Исключение
	//	КонецПопытки;
	//	МассивЗаданий.Очистить();
	//КонецЕсли;

    Сообщить("Время выполнения процедуры - " + (ТекущаяДата() - ВремяНачала) + " с.");
...Показать Скрыть



Почему так интересно?
60. Юрий Осипов (yuraos) 15.04.13 17:31
(59) relanium86,
распараллеливание - не панацея,
это дело как Восток - тонкое.
не все задачи можно распараллелить вообще
и оптимально распарралелить в частности.
61. Антонио (Fragster) 15.04.13 18:04
(59) relanium86, сами по себе фоновые задания запускаются ощутимое время, по этому для операций < десятков секунд смысла вообще нет (или нужны постоянно запущенные задания "в боевой готовности")
62. Дмитрий Шерстобитов (DitriX) 15.04.13 22:09
Да тут вообще по ходу никто толком не решал проблему с распаралеливанием, иначе столкнулись бы с тем же, с чем столкнулись в (58).

Распаралелить в 1С вообще по сути ничего нельзя, по крайней мере до УТ11 и технологии РАУЗ, та и то с ней - спорно все очень.

А видь проблемы то 2:
1. Как собрать, то что получилось;
2. Как не убить сервер нагрузкой.

Я бы на анализ данных, внедрить такое распределение, побоялся бы, ибо там реально больше проблем чем пользы,а еще и поддержка.

А вот на считывание и отправку - это да, например, я для себя сделал такой регистр, в котором есть три измерения (в реале их больше) - Поток, Склад (магазин), флаг начала выгрузки.

И запускается регламент, каждую 1 минуту (это я вывел экспериентальным путем), регламент обращается к регистру и смотрит - есть ли строка выгрузки без флага начала загрузки, если есть - он ставит флаг и идет работать, если все занято - просто отдыхает.

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

Кроме этого - я еще сделал "Вес выгрузки", т.е. я знаю что на 4 склада идет ооочень большая выгрузка, я им сделал вес выше, и при запуске регламента - программа смотрит, если вес больше 20 (крупный склад - Вес = 10, мелкие - от 1 до 5), то он не делает выгрузку.
Таким образом - я не делаю на сервер мгновенную нагрузку, т.е. когда запускается сходу 10 потоков, и все начинают плакать, и не нагружаю сервер.

Но это все костыли, а не многопоточность или мультизадачность :)

(58) а как вы отлавливаете нагрузку на проц? Я тоже думал, но столкнулся с ньюансами, иногда - проц просто на секунд 20 - 30 загружался под 90%, когда были какие то загрузки/выгрузки, и если я попадал на этот промежуток, то я не запускал задания, в итоге - идея оказалось провальной, так как бегая за поддержанием производительности - я тратил в 10 раз больше времени, чем если бы запустил все в одном потоке.

И когда идет вызов фонового задания
63. AlexBar (AlexBar) 15.04.13 22:48
(62)Многопоточность, многозадачность... не суть важно. Вариант ускорения выполнения какого-либо кода все равно имеется в клиент-серверной архитектуре, так что будем пользоваться. Любые рассуждения на тему того, что задания выполняются не совсем параллельно естественно верны, так как сами задания запускаются поочередно в цикле, следовательно если считать время запуска и время выполнения каждого задания равным, то в идеале получим четкую лесенку заданий. То же самое касается и реальной многопоточности. Любой код, и меня не убедят в обратном, выполняется строго линейно и последовательно. Если вызвана процедура или функция то код будет ждать ее завершения прежде чем перейти к следующему шагу. Так что в реальной многопоточности все происходит именно подобным образом. Но это так, отступление.
Загрузку сервера я проверяю через библиотеку WMI методом Win32_Processor. Загрузку проверяет отдельное задание с периодичностью в три секунды (вычисляется эмпирическим путем), результат пишется в константу. Перед запуском очередного задания происходит считывание данных из константы. Если загрузка менее установленного лимита, то можно запускать очередное задание. Лимит так же подбирается с учетом того, что на определение загрузки процессоров так же нужно время, к сожалению оно занимает не доли секунд, и пока вычисляется загрузка процессоров важно не завалить сервер. Кратковременные пиковые загрузки вполне допустимы, если они сопоставимы с ожиданием на блокировках.
Что касается применяемости, то один из вариантов я уже описал.
Впрочем это один из главных разделов, где мы применяем распараллеливание. Я работаю на производственном предприятии со многими переделами и с параметрическими спецификациями (УПП 1.3). Задач, при которых требуется собрать состав большого количества изделий по всем переделам достаточно: расчет плановых цен, расчет потребностей под закупки, расчет загрузки оборудования, пересчет остатков материалов в конечную продукцию (обратная задача - сколько можно сделать из того, что имеем) и прочее и прочее. Применяем данный механизм и в анализе данных, в отчетах. В ближайшее время планируем переделать расчет себестоимости. Так же восстановление некоторых последовательностей выполняем в расспараллеленом режиме: по срезу каждой организации.
Т.е. реальных задач на самом деле предостаточно, где можно применить данный механизм и ускорить работу пользователей, нужно просто включить фантазию.
Кто не хочет применять или не знает на чем применить данный механизм, пусть не применяет. Но критиковать реально работающий механизм.... я пропускаю все это мимо ушей.
jorik31; avto1c; shalimski; dour-dead; KroVladS; w-divin; relanium86; +7 Ответить 2
64. Сергей Бушмакин (relanium86) 16.04.13 06:55
Да действительно если указать число итераций >= 10млн то фоновые задания ускоряют.
Видимо сказывается то что требуется время на запуск фонового задания.
65. Vladimir K (KroVladS) 16.04.13 10:15
(63) AlexBar,
Отличная идея про загрузку сервера, по экспериментируем.

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

не совсем понял как можно распараллелить по организациям?
66. Дмитрий Шерстобитов (DitriX) 16.04.13 12:37
(65) если организации никак не связанны, то почему бы и нет, но если была хотя бы одна продажа или перемещение между ними, то могут быть осложнения.

(63) может быть, однако есть другой способ, более надежный и простой, а еще и гибкий,правда со своими ньюансами,а именно - использование отдельных регистров для определенных задач.

К примеру - есть у меня УТ, там создается дофига чеков ККМ, чеки делаются со склада с типом Оптовый (не спрашивайте почему, так уже было и все обработк/отчеты были заточенны под это), и надо было выгружать информацию по продажам.
Было 3 пути решения - делать выгрузку для каждого склада в своих потоках, либо бежать по ТЧ документов, либо сделать отдельный регист оборотов, куда вся инфа стекалась.
По удобству - был принят третий вариант, так как он позволил в итоге в запросах очень красиов объеденятся с другими данными и т.д.

Я к чему это - реальных задач, которые требуют распаралеливания - не так уж и много, ибо 90% проблем можно решить другими путями с более изящьным подходом.

Любой код, и меня не убедят в обратном, выполняется строго линейно и последовательно.

какое то расплывчатое трактование, в пределах одной инструкции, та и то, спорно, ибо есть метки.
Согласитесь - метки немного искривляют линейность выполнения кода. Последовательно - да, но не линейно.

Если вызвана процедура или функция то код будет ждать ее завершения прежде чем перейти к следующему шагу.

Да ну ладно вам так народ обманывать :)

Вот вам пример реального распаралеливания транзакций:
Я парсю сайт, получил 100 страниц, мне надо их распарсить и поместить в регистр сведений, к примеру, я получаю массив из 100 строк, бегу по циклу и вызываю при помощи vbs. Вот пример:

Например при нажатии на элемент.
Вызывается клиентска функция из нее вот эта:
&НаСервере
Функция Выполнить(ВыбраннаяСтрока)
	Возврат ЭтотОбъект().УточнитьДанные(ДеревоКаталога);	
КонецФункции


Функция УточнитьДанные описанна в модуле обработки
И там же идет парсинг веб страниц и добавление их в дерево описания. Так вот, пока выполняется эта функция - я могу спокойно работать дальше с обработкой и выполнять другие, не связанные с обработкой дерева - потоками.
Однако, как только я вызову еще раз эту функцию, и она дойдет до этапа обновления дерева(при этом первая еще не закончилась), то вылетает в крит сама 1С.
Вот это - реально разные потоки, и вот к чему приводит их применение.
Однако, если я данные буду записывать в регистр, к примеру, а дерево сделать динамическим списком этого регистра - то все выходит ок.

Это я к чему - функция парсинга и т.д. еще выполняется, но программа перешла уже к другой строке кода,и не ждмет завершения предыдущей функции, которая вызывается из модуля.


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

Ага, и учесть последствия, а так же ограниченность платформы.
67. Юрий Осипов (yuraos) 16.04.13 16:59
(65) KroVladS,
наверное имется ввиду,
что у последовательности есть измерение "Организация"
и восстановление последовательности
для каждого значения организации в ней
можно попытаться запустить параллельно
(для каждой организации в своем фоновом задании).
---
если какие-то организации как-то взамимосвязаны
по движениям в регистрах,
то такой подход может оказатся не очень хорошим.
68. Vladimir K (KroVladS) 16.04.13 18:01
(66) DitriX,
если организации никак не связанны, то почему бы и нет

(67) yuraos,
если какие-то организации как-то взамимосвязаны
по движениям в регистрах,
то такой подход может оказатся не очень хорошим.


Я лично не видел ни одной базы в которой ведётся учёт нескольких ни как не связанных организаций. Боле того я не могу представить ситуация при которой это было бы удобно.

Собственно поэтому и задал вопрос.

Опять же восстановление последовательностей - это перепроведение документов в хронологическом порядке,
Из моего опыта при проведении до 50% времени уходит на запись в базу и на запросы с признаком "ДЛЯ ИЗМЕНЕНИЯ", в обоих случаях таблицы заблокированы до завершения транзакции. Тут не то что 10 потоков, даже 3 потока будут друг друга блокировать, не говоря о невозможности работать пользователям.

Всё вышесказанное моё ИХМО, если я не прав пожалуйста покажите мне механизм с помощью которого я мог бы многопоточно восстанавливать последовательность партионного учёта в УТ 10.3.
69. AlexBar (AlexBar) 17.04.13 00:31
(66)
если организации никак не связанны, то почему бы и нет, но если была хотя бы одна продажа или перемещение между ними, то могут быть осложнения.

Совершенно не ясно о каких связях Вы говорите. Когда речь идет об Организации, то однозначно речь идет об юридическом лице, так как для управленческого учета понятие Организация в общем случае не существует. А раз речь идет об юридическом лице, то все остальные организации для этого юридического лица являются всего лишь контрагентами. И совершенно не важно что между ними могут быть перепродажи, давальческие/комиссионные/агентские схемы. Все это взаимоотношения между Организацией и Контрагентом. Учет любой организации является обособленным и самодостаточным и не зависит никоим образом от других организаций в базе данных.
перемещение между ними

Сударь! Я списываю это выражение на то, что Вы пользуетесь своим сленгом, но постарайтесь подобного не произносить в присутствии бухгалтеров и аудиторов.
Исходя из сказанного, если в какой-либо последовательности есть измерение Организация, то восстановление последовательностей в разрезе каждой организации можно вести "параллельно", желательно наложив управляемые блокировки на последовательность по данному измерению.
может быть, однако есть другой способ, более надежный и простой, а еще и гибкий,правда со своими нюансами,а именно - использование отдельных регистров для определенных задач.

Не совсем ясно к чему это относится.
Согласитесь - метки немного искривляют линейность выполнения кода. Последовательно - да, но не линейно.

Линейность в моем понимании и в контексте того, что я говорю, означает буквально что код не может разветвиться. Даже дойдя до метки код перескочит на нее и начнет отрабатывать уже от метки. Т.е. ситуации, когда один контекст ушел на метку, а второй контекст пошел дальше, в природе существовать не может.
То, что Вы описываете далее, я понимаю как использование дополнительных скриптов, которые могут выполняться без ожидания завершения исполнения своего кода. Но это уже не контекст единого приложения. Да и равносильно это тем же фоновым заданиям, которые мы рассматриваем. Вот только в отличии от скриптов фоновые задания выполняются в контексте все того же приложения.
Но в описываемом Вами примере есть положительное рациональное зерно: это может быть альтернативой фоновым заданиям в файловом режиме.
Ага, и учесть последствия, а так же ограниченность платформы.

Если бездумно махать топором, то ошибок можно наделать и в простом математическом выражении, которое напрочь завалит любой сервер.
70. Дмитрий Шерстобитов (DitriX) 17.04.13 11:49

Совершенно не ясно о каких связях Вы говорите. Когда речь идет об Организации, то однозначно речь идет об юридическом лице, так как для управленческого учета понятие Организация в общем случае не существует.

Если бы мы находились в америке или европе - я бы тоже посмеялся, однако, были случаи когда люди продавали товар с одной организации на другу, и делали это по себестоимости, но, так как партии не были выстроенны, то делали по любым ценам, потом в конце месяца выравнивали партии, менялись цены в документе реализации и поступления на новую себестоимость.
Вот вам пример явной зависимости, и пока одна организация дошла до этого документа поступления - она вынуждена ждвть пока вторая организация дойдет то связанного документа продажи, что бы там проставились цены и перенеслись в поступление.
В случае ведения учета по РАУЗ - такой ситуации возникнуть не должно, хотя есть варианты.

Сударь! Я списываю это выражение на то, что Вы пользуетесь своим сленгом, но постарайтесь подобного не произносить в присутствии бухгалтеров и аудиторов.

Тут я согласен, почему то не дошли изменения комментария, я там дальше описывал ситуацию, которая заключалась в том, что если бы не документы перемещения, то и партии по каждому складу отдельно можно было бы выравнивать :) К этому я и написал про перемещения. Разумеется перемещения между организациями быть в принципе не может, так как в документе стоит только одно поле Организация, а скады не связаны явно с организациями.

Не совсем ясно к чему это относится.

Это относится к тому - что далеко не все разумно решать распаралеливанием.

Т.е. ситуации, когда один контекст ушел на метку, а второй контекст пошел дальше, в природе существовать не может.

Я вам привел пример - когда может, и описал последствия :)
А на счет высказанного вами ограничения - то я изначально сказал, что тут надо уточнить - если в пределах одной функции - да, а если нет, то не вегда.

И вообще 1С делает уже хорошие шаги в этом направлении, а именно - возможность регламентного запуска внешних обработок, без надобности лезть в конфигуратор, так сделано в УТ11, но там я еще толком не копался.

З.Ы. Как по мне, так вся эта статья - стоила ваших комментариев :)

(0) ты бы выудил что то из комментариев и обновил статью, тут комментариев на еще одну :)
71. AlexBar (AlexBar) 17.04.13 21:50
(70)
но, так как партии не были выстроенны, то делали по любым ценам, потом в конце месяца выравнивали партии, менялись цены в документе реализации и поступления на новую себестоимость.
Вот вам пример явной зависимости

Я полагаю что Вы согласитесь с тем, что данная зависимость весьма условна. А сама последовательность партионного учета конкретной организации к данной зависимости прямого отношения не имеет. При глубоком рассмотрении данной ситуации при большом желании можно принять некоторые организационные методы, чтобы облегчить жизнь, так как описанная зависимость никак не зависит от способа восстановления последовательности.

Это относится к тому - что далеко не все разумно решать распаралеливанием.

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

P.S. Ваши комментарии так же не менее важны и информативны!
72. Дмитрий Шерстобитов (DitriX) 17.04.13 22:01
(71) считаю спор закрытым, и надеюсь увидиться с вами на конференции. Я думаю мы найдем что друг другу поведать :)
73. Антонио (Fragster) 18.04.13 10:47
(68) KroVladS, Если у последовательности есть измерения - то запросто
74. Андрей Бурмистров (Andreynikus) 22.01.14 21:23
(68) KroVladS,
Я просто оставлю это здесь
http://kb.1c.ru/articleView.jsp?id=72
Aleksey.Bochkov; +1 Ответить 1
75. Vladimir K (KroVladS) 11.02.14 10:16
(74) Andreynikus,
Спасибо конечно за ссылку, но:
-надо было Апреля подождать для надёжности.
-kb.1c.ru закрытый раздел для партнёров, я предполагаю что доступ туда есть только у процентов десяти пользователей инфостара.
-основная идея в статье это разделить документы на независимые группы, при чём так чтобы группы не используются результаты проведения документов друг друга, и проводить их параллельно. Что для последовательности взаиморасчетов вполне реализуемо, а для моей проблемы "партионный учёт" в УТ 10.3 проблематично.

Увидел ваш комментарий только сегодня, почему-то письмо с инфостара о комментариях перестали приходить.
76. Алексей Шачнев (efin) 15.04.15 16:10
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа