Атеджи ПХ
![]() | Тема этой статьи Википедии может не соответствовать общему правилу по известности . ( апрель 2018 г. ) |
Парадигма | объектно-ориентированное исчисление Пи |
---|---|
Дисциплина набора текста | сильный , статичный |
Лицензия | коммерческая, бесплатная 30-дневная пробная версия Premium и бесплатная версия |
Веб-сайт | www.Ateji.com |
Под влиянием | |
Джава |
Ateji PX — это объектно-ориентированное расширение языка программирования для Java . Он предназначен для облегчения параллельных вычислений на многоядерных процессорах , графических процессорах , Grid и Cloud.
Ateji PX может быть интегрирован с Eclipse IDE , требует минимального изучения дополнительных параллельных конструкций и не изменяет процесс разработки.
Примеры кода [ править ]
Привет, мир [ править ]
общественный класс HelloWorld {
public static void main ( String [] args ) {
[
|| Система . вне . println ( "Привет" );
|| Система . вне . println ( "Мир" );
]
}
}
Каждый ||
символ представляет параллельную ветвь. Запуск этой программы выведет либо
Привет Мир
или
Мир Привет
в зависимости от того, как запланированы параллельные ветки.
Параллелизм данных [ править ]
[
|| ( int i : массив . длина ) массив [ я ]++ ;
]
Количественная оценка (int i : N)
создает одну параллельную ветвь для каждого значения i
. Эффект этого кода заключается в увеличении всех элементов array
в параллели. Этот код эквивалентен
[
|| массив [ 0 ]++ ;
|| массив [ 1 ]++ ;
...
|| массив [ массив . длина - 1 ]++ ;
]
Возможны более сложные количественные оценки. В следующем примере выполняется количественная оценка верхнего левого треугольника квадратной матрицы:
[
|| ( int i : N , int j : N , если i + j < N ) матрица [ i ][ j ]++ ;
]
Код, который выполняет аналогичную и обычно небольшую операцию с большой коллекцией элементов, называется параллелизмом данных и часто встречается в высокопроизводительных научных приложениях. Типичным представителем языков с параллельными данными для экосистем C/C++ или Fortran является OpenMP .
Функции параллелизма данных также могут быть реализованы библиотеками с использованием специальных структур данных, таких как параллельные массивы .
Параллелизм задач [ править ]
Термин «параллелизм задач» используется, когда работу можно концептуально разложить на ряд логических задач. В этом примере задачи создаются рекурсивно:
int fib ( int n ) {
if ( n <= 1 ) return 1 ;
интервал фиб1 , фиб2 ;
// рекурсивно создаем параллельные ветки
[
|| фиб1 = фиб ( n - 1 );
|| фиб2 = фиб ( n - 2 );
]
вернуть фиб1 + фиб2 ;
}
Параллелизм задач реализован в таких языках, как Cilk , и в библиотеках, подобных fork/join
пара системных вызовов Unix.
Передача сообщений [ править ]
Параллельные ветки имеют два способа взаимодействия; либо путем одновременного чтения и записи общих переменных, либо путем отправки явных сообщений. Операторы !
и ?
соответственно отправлять и получать сообщения по каналу.
В этом примере две параллельные ветки взаимодействуют посредством явной передачи сообщений:
Чан < Строка > Чан = новый Чан < Строка > ();
[
// ветвь 1 отправляет значение по каналу
|| чан ! "Привет" ;
// ветвь 2 получает значение из канала и печатает его
|| чан ? с ; Система . вне . Печатьln ( ы );
]
Поток данных [ править ]
Программу называют потоком данных, когда вычисления инициируются и синхронизируются наличием данных в потоке. Типичным примером является сумматор: он имеет два входа, один выход, и когда два входа готовы, он отправляет их сумму на выход.
void adder ( Chan < Integer > in1 , Chan < Integer > in2 , Chan < Integer > out ) {
for (;;) {
int value1 , value2 ;
[ в 1 ? значение1 ; || в2 ? значение2 ; ] ;
вне ! значение1 + значение2 ;
}}
Обратите внимание на параллельное чтение [ in1 ? value1; || in2 ? value2; ]
. Это означает, что два входных значения могут идти в любом порядке. Без этого код может зайти в тупик, если значения поступят в неправильном порядке. Это показывает, что параллельные примитивы в языке программирования касаются не только производительности, но и поведения программ.
Сумматор сам по себе ничего не делает, так как реагирует на входные данные. Его необходимо поместить в контекст, в котором другие части передают входные значения и считывают выходные значения. Это можно выразить, объединив все части в большой параллельный блок:
[
|| источник ( с1 ); // генерирует значения в c1
|| источник ( с2 ); // генерирует значения на c2
|| сумматор ( c1 , c2 , c3 );
|| раковина ( с3 ); // читаем значения из c3
]
Все, что можно рассматривать как комбинацию логических элементов или электрических схем, можно легко выразить таким образом как программу потока данных.