Рус Eng Cn Перевести страницу на:  
Please select your language to translate the article


You can just close the window to don't translate
Библиотека
ваш профиль

Вернуться к содержанию

Программные системы и вычислительные методы
Правильная ссылка на статью:

Объектно-транзакционное расширение Cilk++

Пекунов Владимир Викторович

доктор технических наук

Инженер-программист, ОАО "Информатика"

153000, Россия, Ивановская область, г. Иваново, ул. Ташкентская, 90

Pekunov Vladimir Viktorovich

Doctor of Technical Science

Software Engineer, JSC "Informatika"

153000, Russia, Ivanovskaya oblast', g. Ivanovo, ul. Tashkentskaya, 90

pekunov@mail.ru
Другие публикации этого автора
 

 

DOI:

10.7256/2454-0714.2022.3.38823

EDN:

LBFDUK

Дата направления статьи в редакцию:

22-09-2022


Дата публикации:

08-10-2022


Аннотация: В данной работе рассматривается проблема разработки компактных средств, поддерживающих программирование в условиях динамической транзакционной памяти, подразумевающей оперативное порождение транзакционных страниц, для языка Cilk++. Утверждается, что подобная реализация требует ослабленной изоляции транзакций. Анализируется современное состояние проблемы. Отмечается, что существующие решения достаточно громоздки, хотя и позволяют работать со сложными структурами данных, такими как списки и деревья. Утверждается необходимость разработки новых решений в стиле минимализма, основанных на применении специализированных классов (порождающих транзакционные страницы; реализующих согласуемые транзакционные переменные) в сочетании с набором ключевых слов, характерных для Cilk++.   Предлагаются соответствующие новые решения. Вводятся новые элементы синтаксиса, реализуемые с помощью средств расширения языка, характерных для платформы Planning C. Описана семантика новых языковых элементов. Отмечается, что в отличие от аналогов, разработанные средства позволяют декларативно «выстроить» транзакции в сеть (сетевой график работ), определяющую порядок исполнения транзакций и существующий при этом потенциал параллелизма. Проведена апробация предложенного подхода на примере задачи построения гистограммы. Также упоминается об успешном решении с применением разработанных средств задачи обучения искусственной нейронной сети методом обратного распространения ошибки и задачи целочисленного линейного программирования методом ветвей и границ.


Ключевые слова:

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

Abstract: In this paper, we consider the problem of developing compact tools that support programming in dynamic transactional memory, implying operational generation of transactional pages, for the Cilk++ language. It is argued that such an implementation requires weakened transaction isolation. The current state of the problem is analyzed. It is noted that the existing solutions are quite cumbersome, although they allow you to work with complex data structures such as lists and trees. It is argued that it is necessary to develop new solutions in the style of minimalism based on the use of specialized classes (generating transactional pages; implementing consistent transactional variables) in combination with a set of keywords characteristic of Cilk++.   Appropriate new solutions are proposed. New syntax elements are introduced, implemented using language extension tools specific to the Planning C platform. The semantics of new language elements is described. It is noted that, unlike analogues, the developed tools allow declaratively to "build" transactions into a network (network schedule of work), which determines the order of execution of transactions and the potential for parallelism that exists at the same time. The proposed approach was tested on the example of the task of constructing a histogram. It is also mentioned about the successful solution, using the developed tools, of the problem of training an artificial neural network by the method of error back propagation and the problem of integer linear programming by the method of branches and boundaries.


Keywords:

programming language, dynamic transactional memory, object-oriented programming, class library, syntactic constructions, language extension, managing the order of transactions, software transactional memory, Cilk++, transaction network

Введение

В настоящее время параллельное программирование является достаточно обычным видом деятельности для среднего программиста, что объясняется повсеместным использованием многоядерных процессоров. Данный факт обуславливает существование многолетней тенденции к развитию различных простых языковых средств распараллеливания последовательных программ. В частности, весьма перспективным является такое распараллеливание на базе транзакционной памяти, не требующее (в идеальном случае) явного ввода синхронизирующих конструкций [1, 2].

При этом существенный интерес вызывают подходы, базирующиеся на идеях динамической программной транзакционной памяти [3], позволяющие динамически порождать транзакции, опираясь, например, на концепции объектно-ориентированного программирования. Транзакционный объект реализует набор транзакций, его поля, являющиеся, например, наследниками специальных классов, являются согласуемыми переменными. Прочие поля и обычные переменные согласуемыми не являются, реализуя, фактически, некоторое полезное ослабление принципа изолированности транзакций [4, 5].

Недостатками известных автору реализаций такого подхода [3, 6] являются: большое количество дополнительного кода (не только запуск и финализация транзакций, но и получение доступа к согласуемой переменной, явная обработка неудачи такого доступа). Данный факт, видимо, обусловлен требованием возможности параллельно-транзакционной обработки сложных, например, списковых данных, однако при этом имеет место рассогласование с изначальной идеей транзакционной памяти, подразумевающей, что распараллеливание последовательной программы не требует ввода каких-либо синхронизирующих конструктов и существенной переработки программы.

Недостатки существующих подходов определяют потребность в разработке новых, более простых и компактных программных средств работы с динамической транзакционной памятью (например, ориентированных, преимущественно, на обработку классических скалярных переменных и массивов), данная задача является актуальной. При этом существенный интерес вызывают подходы в стиле Cilk++, где, в минимальном варианте, в язык программирования вводятся всего три ключевых слова (cilk_spawn, cilk_sync, cilk_for).

Итак, целью данной работы является упрощение параллельного программирования в условиях динамической программной транзакционной памяти. Для достижения данной цели поставим следующие задачи: а) расширить синтаксис и семантику языка Cilk++, введя в него конструкции для запуска и ожидания транзакций (задача в такой постановке является новой); б) предложить специальную систему классов, содержащую, как минимум, класс, запускающий группу транзакций, и классы транзакционных (согласуемых) переменных; в) реализовать предложенные механизмы в Cilk++, например, используя для этого средства расширения языка, предлагаемые средой Planning C.

Теоретическая часть

Перспективным представляется развитие Cilk++-подхода, состоящее в распространении действия ключевых слов cilk_spawn и cilk_sync не только на функции (классический Cilk++), но и на объекты специальных транзакционных классов, что приводит к порождению объектом новой транзакции (cilk_spawn) или к ожиданию завершения всех запущенных объектом транзакций (cilk_sync). Таких объектов (соответственно и пакетов транзакций) может быть произвольное множество. При этом вполне целесообразен подход, при котором для отдельных транзакционных страниц может быть установлена однозначная последовательность их полного исполнения (от старта и, включая все рестарты, вплоть до финального неотмененного сеанса работы), исключающая необходимость в применении дополнительных конструктов для явной синхронизации запуска транзакций. Добиться этого можно, если cilk_spawn возвращает идентификатор запущенной транзакционной страницы T и, в свою очередь, может иметь в качестве аргументов набор предусловий — идентификаторов транзакционных страниц, которые должны быть завершены до старта страницы T.

Разработаем два специальных шаблонных транзакционных класса, TObj<класс_A> и TQueuedObj<класс_A>, выполняющих функции запуска групп транзакций в динамическом режиме (класс TObj<класс_A> реализует запуск с отказами, если превышено некоторое наперед заданное максимальное количество транзакций, а класс TQueuedObj<класс_A> в таких случаях ставит запуск транзакции в очередь). Если произвольный класс_A имеет поля, являющиеся экземплярами специальных шаблонных классов TArray<тип_B>, TScalar<тип_C>, то классы TObj<класс_A> и TQueuedObj<класс_A> приобретают свойства динамического запуска транзакций с согласуемыми переменными типов TArray<тип_B> (с точки зрения программирования эквивалентны массивам с элементами типа B) и TScalar<тип_C> (с точки зрения программирования эквивалентны простым переменным типа C), а все прочие поля и переменные являются несогласуемыми и на них не распространяется принцип изоляции. При этом cilk_spawn и cilk_sync являются методами классов TObj<класс_A> и TQueuedObj<класс_B> и способны запустить, инкапсулируя в транзакцию, произвольную функцию или метод какого-либо объекта.

Синтаксис

Предложим расширенный синтаксис динамического запуска транзакции:

[идентификатор_переменной «=»] [идентификатор_объекта («.»|«‑>»|«.*»)] «cilk_spawn» [«(» количество_предусловий «,» идентификатор_массива_предусловий «)»] «идентификатор_функции_или_метода» «(» аргументы «)» «;»

аргументы = [аргумент {«,» аргумент}]

аргумент = константа | переменная | «=» переменная

Здесь идентификатор_объекта – идентификатор объекта класса TObj<класс> или TQueuedObj<класс> или их наследника (если запуск конструкции производится внутри какого-либо метода одного из перечисленных классов, то идентификатор объекта можно не указывать, тогда будет использован текущий объект).

Данная конструкция возвращает ненулевой целочисленный идентификатор запущенной транзакции или ноль, если транзакцию запустить временно не удалось (это возможно только для объектов TObj<класс> и их потомков). Массив_предусловий, если он указан, содержит идентификаторы предусловий, то есть тех транзакций, которые должны быть завершены до старта данной. Что же касается аргументов, то следует обратить особое внимание на случай передачи локальной переменной – если есть опасность, что транзакция завершится позже текущего локального блока, то декларированные в нем переменные следует передавать с префиксом «=», который создаст внутренние копии таких переменных.

Теперь рассмотрим расширенный синтаксис конструкции ожидания завершения всех запущенных объектом транзакций:

[идентификатор_объекта («.»|«‑>»|«.*»)] «cilk_sync» «;»;

Здесь идентификатор_объекта – также идентификатор объекта класса TObj<класс> или TQueuedObj<класс> или их наследника.

Апробация

Предложенные синтаксические нововведения были реализованы с применением средств построения языковых расширений Planning C. Были разработаны соответствующие дедуктивные макросы cilk_spawn и cilk_sync, а также написана библиотека транзакционных классов и переменных.

В качестве простого примера применения рассмотрим построение гистограммы. Здесь основным рабочим классом является Histogrammer, метод process которого выполняет полезную работу по обработке одного элемента исходного массива (для которого строится гистограмма). Согласуемой переменной является поле – виртуальный массив F, представляющий массив частот.

Транзакционным классом является, соответственно, TQueuedObj<класс_Histogrammer>, на котором запускаются транзакции, в рамках каждой из которых выполняется метод process со специфическими параметрами. Этот же класс выполняет и ожидание завершения всех транзакций при вызове cilk_sync.

#include <stdlib.h>

#include < iostream >

#include <omp.h>

using namespace std;

#include "transacted.h"

const int N = 10000;

const int M = 600;

const int NF = 20;

class Histogrammer {

public:

TArray< int > * F;

Histogrammer(int nthreads) {

F = new TArray< int >(NF);

*F = 0;

}

void process(int * A, double grain, int i) {

int k = A[i] / grain;

if (k >= NF) k = NF - 1;

++((*F)[k]);

}

~Histogrammer() {

delete F;

}

};

int main() {

int * A = new int[N];

srand(184415);

for (int i = 0; i < N; i++)

A[i] = rand() % M;

double grain = 1.0 * M / NF;

TQueuedObj< Histogrammer > obj(omp_get_num_procs());

for (int i = 0; i < N; i++)

obj.cilk_spawn obj.process(A, grain, =i);

obj.cilk_sync;

int SF = 0;

for (int i = 0; i < NF; i++)

SF += (*obj.F)[i];

cout << SF;

delete[] A;

return 0;

}

Данная программа успешно исполняется, выдавая в качестве результата число «10000».

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

Выводы

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

Библиография
1. M. Herlihy and J. E. B. Moss. Transactional memory: Architectural support for lock-free data structures. In A. J. Smith, editor, Proceedings of the 20th Annual International Symposium on Computer Architecture. San Diego, CA, May 1993, pages 289–300. ACM, 1993.
2. Marathe, V.J., Scherer, W.N., Scott, M.L. (2005). Adaptive Software Transactional Memory. In: Fraigniaud, P. (eds) Distributed Computing. DISC 2005. Lecture Notes in Computer Science, vol 3724. Springer, Berlin, Heidelberg. https://doi.org/10.1007/11561927_26
3. Herlihy, M., Luchangco, V., Moir, M., and Scherer, W.N. 2003. Software transactional memory for dynamic-sized data structures. In Proceedings of the twenty-second annual symposium on Principles of distributed computing (PODC '03). Association for Computing Machinery, New York, NY, USA, 92–101. https://doi.org/10.1145/872035.872048
4. Miculan, M., Peressotti, M. Software Transactional Memory with Interactions. Proceedings of the 21st Italian Conference on Theoretical Computer Science, Ischia, Italy, September 14-16, 2020, pp.67-80.
5. V. Luchangco and V. J. Marathe. Transaction communicators: Enabling cooperation among concurrent transactions. In Proceedings of the 16th ACM Symposium on Principles and Practice of Parallel Programming, PPoPP ’11, pages 169–178, New York, NY, USA, 2011. ACM.
6. Marathe, V.J., Spear, M.F., Heriot, C., Acharya, A., Eisenstat, D., Scherer III, W.N., and Scott, M.L. Lowering the Overhead of Software Transactional Memory. Dept. of Computer Science, Univ. of Rochester, March 2006. URL: https://www.cs.rochester.edu/u/scott/papers/2006_TR893_RSTM.pdf (Дата обращения: 19.09.2022)
References
1. M. Herlihy and J. E. B. Moss. (1993). Transactional memory: Architectural support for lock-free data structures. In A. J. Smith, editor, Proceedings of the 20th Annual International Symposium on Computer Architecture. San Diego, CA, May 1993, pages 289–300. ACM, 1993.
2. Marathe, V.J., Scherer, W.N., Scott, M.L. (2005). Adaptive Software Transactional Memory. In: Fraigniaud, P. (eds) Distributed Computing. DISC 2005. Lecture Notes in Computer Science, vol 3724. Springer, Berlin, Heidelberg. https://doi.org/10.1007/11561927_26
3. Herlihy, M., Luchangco, V., Moir, M., and Scherer, W.N. (2003). Software transactional memory for dynamic-sized data structures. In Proceedings of the twenty-second annual symposium on Principles of distributed computing (PODC '03). Association for Computing Machinery, New York, NY, USA, 92–101. https://doi.org/10.1145/872035.872048
4. Miculan, M., Peressotti, M. (2020). Software Transactional Memory with Interactions. Proceedings of the 21st Italian Conference on Theoretical Computer Science, Ischia, Italy, September 14-16, 2020, pp.67-80.
5. V. Luchangco and V. J. Marathe. (2011). Transaction communicators: Enabling cooperation among concurrent transactions. In Proceedings of the 16th ACM Symposium on Principles and Practice of Parallel Programming, PPoPP ’11, pages 169–178, New York, NY, USA, 2011. ACM.
6. Marathe, V.J., Spear, M.F., Heriot, C., Acharya, A., Eisenstat, D., Scherer III, W.N., and Scott, M.L. (2006). Lowering the Overhead of Software Transactional Memory. Dept. of Computer Science, Univ. of Rochester, March 2006. URL: https://www.cs.rochester.edu/u/scott/papers/2006_TR893_RSTM.pdf

Результаты процедуры рецензирования статьи

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

Представленная на рецензирование статья посвящена применению многоядерных процессоров, параллельному программированию и объектно-транзакционному расширению Cilk++.
Методология исследования базируется на обобщении научных публикаций по выбранной теме, программной реализации предлагаемого подхода на языке программирования Planning C.
Актуальность работы обусловлена распространением применения многоядерных процессоров, параллельного программирования и стремлением к его упрощению в условиях применения динамической программной транзакционной памяти. По мнению автора, недостатки существующих подходов определяют потребность в разработке новых, более простых и компактных программных средств работы с динамической транзакционной памятью.
Научная новизна рецензируемого исследования, по мнению рецензента заключается в разработке и программной реализации на языке Planning C объектно-транзакционного расширения Cilk++, позволяющего работать с динамической транзакционной памятью, отличающееся минимализмом набора конструкций и возможностью определения порядка обработки транзакций с помощью предусловий запуска.
В статье структурно выделены следующие разделы: Введение, Теоретическая часть, Синтаксис, Апробация, Выводы и Библиография. Во введении обоснована актуальность исследования, сформулированы его цель и задачи. Далее изложены перспективные направления развития Cilk++-подхода, предложен расширенный синтаксис динамического запуска транзакции, изложена особенность предлагаемой конструкции. Автор отстаивает целесообразность использования подхода, при котором для отдельных транзакционных страниц может быть установлена однозначная последовательность их полного исполнения, исключающая необходимость в применении дополнительных конструктов для явной синхронизации запуска транзакций. В ходе апробации предложенные синтаксические нововведения были реализованы с применением средств построения языковых расширений Planning C, были разработаны дедуктивные макросы, а также написана библиотека транзакционных классов и переменных.
Библиографический список включает 6 источников – публикации иностранных авторов в зарубежных журналах теме статьи. В тексте имеются адресные ссылки на литературные источники, подтверждающие наличие апелляции к оппонентам.
В качестве замечаний можно отметить следующие моменты. Во-первых, вряд ли стоит ограничиваться обобщением публикаций исключительно из зарубежных источников с учетом того, что в отечественных научных журналах имеется немало работ, посвященных многопроцессорным вычислительным систем и параллельному программированию. Во-вторых, автор утверждает, что с применением предложенных средств были решены задачи параллельного обучения искусственной нейронной сети прямого распространения и задача целочисленной линейной оптимизации методом ветвей и границ, однако, в тексте эти разработки не приведены, ссылки на уже опубликованные работы автора по этой проблематике также не указаны.
Рецензируемый материал соответствует направлению журнала «Программные системы и вычислительные методы», подготовлен на актуальную тему, содержит теоретические обоснования, элементы научной новизны и практической значимости.