Unified Parallel C (UPC)
Парадигма Паралельна, імперативна (процедурна), структурна
Дата появи 1999
Творці UPC Consortium
Останній реліз 2.12.2/2011-5-18
Система типізації Статична
Основні реалізації GNU UPC, IBM XL UPC Compilers, HP UPC, Berkeley UPC, Michigan Tech MuPC, Cray UPC
Під впливом від C, AC,Split-C, Parallel C Preprocessor
Операційна система Крос-платформена
Вебсайт upc.gwu.edu

Unified Parallel C (UPC) - розширення мови програмування С, призначене для високопродуктивних обчислень на масштабних паралельних комп'ютерах, в тому числі на SMP/NUMA системах з загальною пам'яттю (єдиним адресним простором) і з розподіленою пам'яттю (наприклад, на кластерах). Програмісту надається доступ до всього глобального розділеного адресного простору (PGAS), збережені в ньому змінні можуть читатися і змінюватися будь-яким процесором. При цьому кожне значення зберігається у фізичній пам'яті одного з процесорів. UPC використовує модель SPMD (Single Program Multiple Data) в якій ступінь паралелізму фіксується при запуску програми, зазвичай на рівні один потік виконання на ядро ​​процесора.

Для вираження паралелізму UPC додає до ISO C 99 конструкції:

На UPC значно вплинули три більш ранніх паралельних розширення: ISO C 99: AC, Split-C[en], і Parallel C Preprocessor (PCP). UPC не є їхньою надбудовою, а скоріше спробою об'єднати кращі їх сторони. UPC комбінує зручність програмування в парадигмі загальної пам'яті, рівень контролю за розподілом даних і продуктивності парадигми передачі повідомлень. Підтримується на різних HPC платформах.

UPC доволі простий в програмуванні, особливо для С-програмістів та порівнянні с іншими парадигмами паралельного програмування (MPI, Charm++). Продуктивність UPC схожа з MPI.

Вручну оптимізований код с блоковими пересилками даних, все ж значно простіше, ніж MPI. Мова і середовище виконання (runtime) беруть на себе рутинну роботу по комунікації.

Особливості UPC

Філософія

Філософія мови схожа на С:

Реалізації

Існують різні реалізації стандарту UPC:

Доступні засоби розробки і налагодження:

Основні елементи

1) Два типи змінних:

2) Shared масиви і розподіл даних по процесорам;

3) Розподіл обчислень по процесорам;[1]

4) Синхронізація і забезпечення консистентності пам'яті;

Модель виконання

Декілька потоків виконують одну і ту ж програму, але обробляють різні дані (SPMD):

Синхронізація застосовується тільки тоді, коли це необхідно:

Рис. 1 Представлення

Модель представлення пам'яті

Пам'ять розподілена між потоками, частина цієї пам'яті є локальною і доступна тільки потоку - власнику, інша частина пам'яті — глобальна (доступна для всіх потоків).

Управління розподілом даних

Приклади:[1]

Рис. 2. Результат прикладу
shared int x; /* will have affinity to thread 0 */
shared int y[THREADS];
int z;

THREADS = 3 /* нехай буде 3 потоки */
Рис. 3. Результат (sharedintA[4][THREADS])
sharedintA[4][THREADS];

Блоковий розподіл даних (за замовчуванням розмір блоку 1)

shared [block - size ] type array[N];

Приклад:

Рис. 4. THREADS = 4
shared [3] int A [4] [THREADS];
THREADS = 4;

Матричне множення

Рис. 5. Результат матричного множення
// vect_mat_mult.c
#include<upc_relaxed.h>
shared[THREADS] int a[THREADS][THREADS];
shared int b[THREADS], c[THREADS];
void main (void){
    nt i, j; 
    upc_forall( i = 0 ; i < THREADS ; i++; i){
        c[i] = 0;
        for( j=0 ; j< THREADS ; j++)
          c[i] += a[i][j]*b[j];
    }
}

Приклад паралельного скалярного множення

Приклад:[2]

# include <upc_relaxed.h>
# define N 1000 * THREADS

shared float A[N], B[N];
shared float MUL[N];

void scalar_mul_a_b()
{
   int i;
   upc_forall(i = 0; i < N; i++; i)
       MUL[i] = A[i] * B[i];
}

Розпаралелювання циклів

Синтаксис

upc_forall (init; test; loop; affinity)

statyment

Семантика

Приклад

shared int a [100], b[100], c[100];
int i;
upc_forall (i = 0; i<100; i++; a[i])
    a[i] = b[i] * c[i];

Службові операції

Отримання розміру локальної частини глобального об'єкта:

upc_localsizeof (type-name or expression);

Отримання розміру блока глобального об'єкта:

upc_blocksizeof ( type - name or expression);

Отримання розміру елемента глобального об'єкта:

upc_elemsizeof ( type - name or expression);

Операції копіювання і ініціалізації

Копіювання з загальної пам'ять в загальну

upc_memcpy (dst, src, size)

Копіювання з локальної пам'яті в загальну

upc_memput (dst, src, size)

Копіювання з загальної пам'яті в локальну

upc_memget (dst, src, size)

Ініціалізація загальної пам'яті

upc_memset (dst, src, size)

Використовуваний блок загальної пам'яті повинен бути безперервним і належати одному і тому ж потоку!

Динамічний розподіл пам'яті

  1. Динамічний розподіл пам'яті можливий для загальної пам'яті;
  2. Операції виділення пам'яті можуть бути, як колективними, так і локальними для потоків ( префікс колективних операцій - all ).

Синтаксис

shared void *upc_all_alloc ( size_t nblocks, size_t nbytes );

Семантика

Джерела

  1. а б в г lecture_120710_fedulova (PDF). Архів оригіналу (PDF) за 1 грудня 2016.
  2. а б http://upc.gwu.edu/tutorials/UPC-SC05.pdf [Архівовано 31 січня 2012 у Wayback Machine.] slide 21

Посилання