Unified Parallel C

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до навігації Перейти до пошуку
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:

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

  • TotalView;
  • Eclipse Parallel Tools Platform.[1]

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

[ред. | ред. код]

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

  • Private (за замовчуванням );
  • Shared (спеціальна директива).

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

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

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

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

[ред. | ред. код]

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

  • Подібно MPI;
  • Немає неявної синхронізації;
  • MYTHREAD - номер даного потоку, THREADS - загальна кількість потоків;
  • Число потоків може задаватися під час компіляції, так і під час виконання (подібно mpirun - np N)

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

  • Бар'єри;
  • Блокування (Locks);
  • Контроль консистентності пам'яті.[1]
Рис. 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

Семантика

[ред. | ред. код]
  • Ітерації циклу виконуються в потоках відповідно до локалізації параметра "affinity";
  • affinity - цілочисельний вираз або посилання на загальний об'єкт.[2]

Приклад

[ред. | ред. код]
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 );

Семантика

[ред. | ред. код]
  • Виділення загальної (глобальної) пам'яті;
  • block_size - розмір блока, nblocks - кількість блоків;
  • Результат виділення пам'яті відповідає дійсності:
    shared[nbytes] char[nblocks* nbytes]
    
  • Дана операція виділення пам'яті є колективною.
  • Виділення загальної пам'яті тільки для поточного потоку, виконується за допомогою функції upc_global_alloc.

Джерела

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

Посилання

[ред. | ред. код]