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:
Доступні засоби розробки і налагодження:
1) Два типи змінних:
2) Shared масиви і розподіл даних по процесорам;
3) Розподіл обчислень по процесорам;[1]
4) Синхронізація і забезпечення консистентності пам'яті;
Декілька потоків виконують одну і ту ж програму, але обробляють різні дані (SPMD):
Синхронізація застосовується тільки тоді, коли це необхідно:
Пам'ять розподілена між потоками, частина цієї пам'яті є локальною і доступна тільки потоку - власнику, інша частина пам'яті — глобальна (доступна для всіх потоків).
Приклади:[1]
shared int x; /* will have affinity to thread 0 */
shared int y[THREADS];
int z;
THREADS = 3 /* нехай буде 3 потоки */
sharedintA[4][THREADS];
shared [block - size ] type array[N];
Приклад:
shared [3] int A [4] [THREADS];
THREADS = 4;
// 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)
Використовуваний блок загальної пам'яті повинен бути безперервним і належати одному і тому ж потоку!
shared void *upc_all_alloc ( size_t nblocks, size_t nbytes );
shared[nbytes] char[nblocks* nbytes]