DRAM - Європейський університет

Download Report

Transcript DRAM - Європейський університет

Європейський Університет
кафедра інформаційних систем та технологій
Програмування паралельних
систем:
кластери, багатоядерні та графічні процесори
Канд. фіз.-мат. наук, доцент
Єршов Сергій Володимирович
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
© 2011 ЄУ
Сучасні засоби програмування паралельних систем
•
•
•
MPI (Message Passing Interface, інтерфейс
передачі повідомлень) - стандарт програмного
інтерфейсу для паралельних систем із розподіленою
пам’яттю (мультикомп’ютери, кластери). Існують
реалізації для мов C++, C, Fortran, Java.
Open Multi-Processing (OpenMP) - стандарт
програмного інтерфейсу для паралельних систем із
спільною пам'яттю (багатоядерні системи).
Підтримує мови C, C++, Fortran.
CUDA (Compute Unified Device Architecture) –
програмно-апаратна архітектура, що дозволяє
здійснювати паралельні обчислення на спеціальному
спрощеному діалекті мови програмування С з
використанням графічних процесорів NVIDIA.
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
-2-
© 2011 ЄУ
Message Passing Interface (MPI)
В обчислювальних системах з
розподіленою пам'яттю процесори
працюють незалежно один від
одного.
Для організації паралельних
обчислень необхідно уміти:
П роцесор
П роцесор
К еш
К еш
Л ін ії
перед ачі
д аних
О перативна
пам ’ять
О перативна
пам ’ять
• розподіляти обчислювальне навантаження,
• організувати інформаційну взаємодію (передачу даних)
між процесорами.
Вирішення всіх перерахованих питань забезпечує
MPI-інтерфейс передачі даних (message passing interface)
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
-3-
© 2011 ЄУ
Розробка паралельних програм з використанням MPI
Основи MPI
•
Іниціализація та завершенння MPI програм
•
структура паралельної програми, яка розроблена з
використанням MPI, має наступний вигляд:
#include "mpi.h"
int main ( int argc, char *argv[] ) {
<програмний код без використання MPI функцій>
MPI_Init ( &agrc, &argv );
<програмний код з використанням MPI функцій >
MPI_Finalize();
<програмний код без використання MPI функцій >
return 0;
}
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
-4-
© 2011 ЄУ
Область взаємодії
•
описується спеціальною структурою -
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
комунікатором
-5-
© 2011 ЄУ
Розробка паралельних програм з використанням MPI
Основи MPI
•
Визначення кількості та рангу процесів
•
Як правило, виклик функцій MPI_Comm_size та
MPI_Comm_rank виконується відразу після MPI_Init:
#include "mpi.h"
int main ( int argc, char *argv[] ) {
int ProcNum, ProcRank;
<програмний код без використання MPI функцій>
MPI_Init ( &agrc, &argv );
MPI_Comm_size ( MPI_COMM_WORLD, &ProcNum);
MPI_Comm_rank ( MPI_COMM_WORLD, &ProcRank);
<програмний код з використанням MPI функцій >
MPI_Finalize();
<програмний код без використання MPI функцій >
return 0;
}
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
-6-
© 2011 ЄУ
Розробка паралельних програм з використанням MPI
Основи MPI
• Паралельна програма з використанням MPI
#include " mpi.h "
int main(int argc, char* argv[]) {
int ProcNum, ProcRank, RecvRank;
MPI_Status Status; MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &ProcNum);
MPI_Comm_rank(MPI_COMM_WORLD, &ProcRank);
if ( ProcRank == 0 ) { // Дії для процесу 0
printf ("\n Hello from process %3d", ProcRank);
for ( int i=1; i < ProcNum; i++ ) {
MPI_Recv(&RecvRank, 1, MPI_INT, MPI_ANY_SOURCE,
MPI_ANY_TAG, MPI_COMM_WORLD, &Status);
printf("\n Hello from process %3d", RecvRank);
}
}
else // Дії для всіх процесів, окрім процесу 0
MPI_Send(&ProcRank,1,MPI_INT,0,0,MPI_COMM_WORLD);
// Завершення роботи
MPI_Finalize();
return 0;
}
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
-7-
© 2011 ЄУ
Форми обміну повідомленнями
•
Двоточковий обмін (point-to-point)
• Односторонній обмін
 Колективний обмін
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
-8-
© 2011 ЄУ
Блокуючий обмін повідомленнями
Send(buf, 2)
Recv(buf, 1)
БЛОКУВАННЯ
ЧАС
процес 2
процес 1
БЛОКУВАННЯ
“КВИТАНЦІЯ”
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
-9-
© 2011 ЄУ
Неблокуючий обмін повідомленнями
процес 2
Test(1)->false
Send(buf, 2)
Test(1)->false
ЧАС
процес 1
Test(1)->false
Test(1)->true
Recv(buf, 1)
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 10 -
© 2011 ЄУ
Розробка паралельних програм з використанням MPI
Знайомство з колективними операціями передачі даних
• Передача даних від одного процесу всім процесам програми
•
Функція MPI_Bcast здійснює розсилку даних з буфера buf,
що містить count елементів типу type з процесу, який має
номер root, всім процесам, що входять в комунікатор comm
проц еси
проц еси
0
0
1
1

root
*


root
*

*
*


p-1
p-1
а) до початк у операц ії
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
*
б) після заверш ення оп ерації
- 11 -
© 2011 ЄУ
Розробка паралельних програм з використанням MPI
Знайомство з колективними операціями передачі даних
• Передача даних від всіх процесів одному процесу
•
Процедура збору і подальшого підсумовування даних - приклад часто
виконуваної колективної операції передачі даних від всіх процесів
одному процесу, у якій над збираними значеннями здійснюється
обробка даних.
проц еси
проц еси
0
0
x00 x01 x02

x 0 ,n -1
1
1
x10 x11 x12

x 1 ,n -1

x i,n -1


root
y0 y1 y2

y n -1


i
x i0 x i1 x i2

а) після заверш ення оп ерації
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
у j   x ij , 0  j  n

p-1
p-1
x n -1 ,0 x n -1 ,1
n 1
i0

x n -1 ,n -1
б) до початк у оп ерац ії
- 12 -
© 2011 ЄУ
Приклад: Обчислення числа 
 Значення числа  може бути отримано за
допомогою інтеграла
1
 
4
1 x
2
dx
0
 Для чисельного інтегрування застосуємо
метод прямокутників
4
3
2
1
0
0
0,25
0,5
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
0,75
1
- 13 -
© 2011 ЄУ
Приклад: Обчислення числа 
 Розподілимо обчислення між p процесорами
(циклічна схема)
 Отримувані на окремих процесорах
часткові суми мають бути підсумовані
4
- Процесор 0
- Процесор 1
3
- Процесор 2
2
1
0
0
0,25
0,5
0,75
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
1
- 14 -
© 2011 ЄУ
Приклад: Обчислення числа 
#include "mpi.h"
#include <math.h>
double f(double a) {
return (4.0 / (1.0 + a*a));
}
int main(int argc, char *argv) {
int ProcRank, ProcNum, done = 0, n = 0, i;
double PI25DT = 3.141592653589793238462643;
double mypi, pi, h, sum, x, t1, t2;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&ProcNum);
MPI_Comm_rank(MPI_COMM_WORLD,&ProcRank);
while (!done ) { // основний цикл обчислень
if ( ProcRank == 0) {
printf("Enter the number of intervals: ");
scanf("%d",&n);
t1 = MPI_Wtime();
}
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 15 -
© 2011 ЄУ
Приклад: Обчислення числа 
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (n > 0) { // обчислення локальних сум
h = 1.0 / (double) n;
sum = 0.0;
for (i = ProcRank + 1; i <= n; i += ProcNum) {
x = h * ((double)i 0.5);
sum += f(x);
}
mypi = h * sum;
// складання локальних сум (редукція)
MPI_Reduce(&mypi,&pi,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD
);
if ( ProcRank == 0 ) { // виведення результатів
t2 = MPI_Wtime();
printf("pi is approximately %.16f, Error is
%.16f\n",pi, fabs(pi PI25DT));
printf("wall clock time = %f\n",t2-t1);
}
} else done = 1;
}
MPI_Finalize();
}
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 16 -
© 2011 ЄУ
Тенденції розвитку сучасних процесорів
Потік
О
О
П
О
П
Потік (“thread”) – це
легковагий процес,
що має з іншими
потоками спільні
ресурси, в тому числі
спільну оперативну
пам'ять.
П
збільшили продуктивність процесора в 2 рази
Потік
О
П
П
О
П
О
Час
Потік 3
О
Потік 2
Потік 1
О
О
В - обчислення
О
П
О
П
П
О
П
О
Потік 4
О
О
П
О
П
П
О
П
О
П
П
П
П
Час
П - доступ до пам’яті
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
Chip
MultiThreading
- 17 -
© 2011 ЄУ
Тенденції розвитку сучасних процесорів
Intel Xeon серії 5600 (Nehalem)
X5680 6 ядер @ 3,33 ГГц, 12 потоків, 12 МБ L3 Cache
X5677 4 ядра @ 3,46 ГГц, 8 потоків, 12 МБ L3 Cache
Intel® Turbo Boost
Intel® Hyper-Threading
Intel® QuickPath
Intel® Intelligent Power
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 18 -
© 2011 ЄУ
Переваги використання OpenMP замість MPI для
багатоядерних процесорів





Можливість інкрементального розпаралелювання
Спрощення програмування і ефективність на
нерегулярних обчисленнях, що проводяться над
спільними даними
Ліквідація дублювання даних в пам'яті, що властиве
MPI-програмам
Останніми роками спостерігається тенденція до
скорочення обсягу оперативної пам'яті, що виділяється
на одне ядро. Властива OpenMP економія пам’яті стає
дуже важливою.
Наявність локальних КЕШів (і/або таких, що
розділяються ядрами) враховуватиметься при
оптимізації OpenMP-програм компіляторами, що не
можуть робити компілятори послідовних мов для
MPI-процесів.
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 19 -
© 2011 ЄУ
Виконання OpenMP-програми
•


Fork-Join паралелізм:
Головний (master) потік породжує групу (team) потоків
за мірою необхідності.
Паралелізм додається інкрементально.
Паралельні області
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 20 -
© 2011 ЄУ
Модель пам’яті в OpenMP
001
Потік
001
Потік
Потік
001
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 21 -
© 2011 ЄУ
Модель пам’яті в OpenMP
… = i + 1;
i=0
static int i = 0;
i=1
#pragma omp flush (i)
i=1
#pragma omp flush (i)
001 1
Потік
i = i + 1; i = 1
001 0
Потік
… = i + 2; // ?
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 22 -
© 2011 ЄУ
Класи перемінних
•
•
•
•
•
•
•
•
•
double Array1[100];
int main() {
int Array2[100];
#pragma omp parallel
{ int iam =
omp_get_thread_num();
work(Array2, iam);
printf(“%d\n”, Array2[0]);
}
}
TempArray, iam
Array1, Array2,
count
TempArray,iam
extern double
Array1[100];
void work(int *Array, int
iam) {
double
TempArray[100];
static int count;
...
}
Array1, Array2,
count
TempArray,iam
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 23 -
© 2011 ЄУ
Обчислення числа  з використанням OpenMP
#include <stdio.h>
int main ()
{
int n =100000, i;
double pi, h, sum, x;
h = 1.0 / (double) n;
sum = 0.0;
#pragma omp parallel for reduction(+:sum) private(x)
for (i = 1; i <= n; i ++)
{
x = h * ((double)i - 0.5);
sum += (4.0 / (1.0 + x*x));
}
pi = h * sum;
printf("pi is approximately %.16f”, pi);
return 0;
}
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 24 -
© 2011 ЄУ
Використання директиви task
typedef struct node node;
struct node {
int data;
node * next;
};
void increment_list_items(node * head)
{
#pragma omp parallel
{
#pragma omp single
{
node * p = head;
while (p) {
#pragma omp task
process(p);
p = p->next;
}
}
}
}
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 25 -
© 2011 ЄУ
Програмна модель CUDA
• Масштабованість на десятки ядер, сотні
паралельних потоків
• Дозволяє сфокусуватися на розробці
паралельних алгоритмів
– А не внутрішніх засобах мови програмування
• Підтримує гетерогенні обчислення
–CPU для послідовного коду, GPU – для
паралельного
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 26 -
© 2011 ЄУ
Масивно-паралельні системи на основі архітектури CUDA
Мультипроцесор Tesla 10
Streaming Multiprocessor
Instruction $
Instruction Fetch
Texture Processing Cluster
Shared Memory
SM
TEX
SM
SM
Constant $
SP
SP
SP
SP
SFU
SP
SP
SP
SP
SFU
Register File
Double Precision
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 27 -
© 2011 ЄУ
Масивно-паралельні системи на основі архітектури CUDA
Архітектура Tesla 10
CPU
Bridge
Host Memory
Work Distribution
TPC
TPC
TPC
TPC
TPC
TPC
TPC
TPC
TPC
TPC
Interconnection Network
ROP
L2
DRAM
ROP
L2
DRAM
ROP
L2
DRAM
ROP
L2
DRAM
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
ROP
L2
DRAM
ROP
L2
DRAM
ROP
L2
DRAM
- 28 -
ROP
L2
DRAM
© 2011 ЄУ
Програмна модель CUDA
•
•
•
•
•
•
GPU (device) - це обчислювальний пристрій,
який:
• Є співпроцесором до CPU (host)
• Має власну пам'ять (DRAM)
• Виконує одночасно дуже багато ниток
Паралельна частина коду виконується як велика
кількість потоків
Потоки групуються в блоки фіксованого розміру
Блоки об'єднуються в сітку блоків
Ядро виконується на сітці з блоків
Кожний потік і блок мають свій ідентифікатор
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 29 -
© 2011 ЄУ
Програмна модель CUDA
• Десятки тисяч потоків
for (int ix = 0; ix < nx;
ix++)
{
pData[ix] = f(ix);
}
for (int ix = 0; ix < nx; ix++)
for (int iy = 0; iy < ny; iy++)
{
pData[ix + iy * nx] = f(ix) * g(iy);
}
for (int ix = 0; ix < nx; ix++)
for (int iy = 0; iy < ny; iy++)
for (int iz = 0; iz < nz; iz++)
{
pData[ix + (iy + iz * ny) * nx] = f(ix) * g(iy) * h(iz);
}
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 30 -
© 2011 ЄУ
Програмна модель CUDA
•
Потоки в CUDA об’єднуються в блоки:
• Можлива 1D, 2D, 3D топологія блоку
• Загальна кількість потоків в блоці є обмежена
• У сучасному HW це 512 потоків
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 31 -
© 2011 ЄУ
Програмна модель CUDA
• Потоки в одному блоці можуть розділяти ресурси
зі своїми сусідами
float g_Data[gN];
for (int ix = 0; ix < nx; ix++)
{
pData[ix] = f(ix, g_Data[ix / n]);
}
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 32 -
© 2011 ЄУ
Програмна модель CUDA
•
Блоки потоків об’єднуються в сітку (grid) потоків
• Можлива 1D, 2D топологія сітки блоків потоків
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 33 -
© 2011 ЄУ
Синтаксис CUDA
•
•
CUDA – це розширення мови C
• [+] специфікатори для функцій та
перемінних
• [+] нові вбудовані типи
• [+] вбудовані перемінні (усередині ядра)
• [+] директива для запуску ядра з C коду
Як скомпілювати CUDA код
• [+] nvcc компілятор
• [+] .cu розширення файлу
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 34 -
© 2011 ЄУ
Синтаксис CUDA
•
Порівняємо код для CPU з кодом CUDA kernel:
float * pData;
for (int ix = 0; ix < nx; ix++)
{
pData[ix] = pData[ix] + 1.0f;
}
nx = 2048
У блоці 256 потоків
 кількість блоків
= 2048 / 256 = 8
__global__ void incKernel ( float * pData )
{
int idx = blockIdx.x
* blockDim.x
+ threadIdx.x;
[ 0 .. 7 ]
[ == 256]
[ 0 .. 255 ]
pData [idx] = pData [idx] + 1.0f;
}
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 35 -
© 2011 ЄУ
Синтаксис CUDA. Директиви запуску ядра
•
Як запустити ядро із загальною кількістю потоків, що
дорівнює nx?
float * pData;
dim3 threads(256, 1, 1);
dim3 blocks(nx / 256, 1);
Неявно припускаємо,
що nx кратне 256
incKernel<<<blocks, threads>>> ( pData );
<<< , >>>
кутові дужки, усередині яких задаються
параметри запуску ядра:
• Кількість блоків в сітці
• Кількість потоків у блоці
•…
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 36 -
© 2011 ЄУ
Типи пам’яті в CUDA
Тип пам’яті
Доступ
Рівень
виділення
Швидкість роботи
Регістри
R/W
Per-thread
Висока (on-chip)
Локальна
R/W
Per-thread
Низька (DRAM)
Shared
R/W
Per-block
Висока (on-chip)
Глобальна
R/W
Per-grid
Низька (DRAM)
Constant
R/O
Per-grid
Висока (L1 cache)
Texture
R/O
Per-grid
Висока (L1 cache)
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 37 -
© 2011 ЄУ
Множення матриць в CUDA
#define BLOCK_SIZE 16
__global__ void matMult (float* a, float* b, int n, float* c)
{
int
bx = blockIdx.x;
int
by = blockIdx.y;
int
tx = threadIdx.x;
int
ty = threadIdx.y;
float sum = 0.0f;
int
ia = n * BLOCK_SIZE * by + n * ty;
int
ib = BLOCK_SIZE * bx + tx;
int
ic = n * BLOCK_SIZE * by + BLOCK_SIZE * bx;
for ( int k = 0; k < n; k++ )
sum += a [ia + k] * b [ib + k*n];
c [ic + n * ty + tx] = sum;
}
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 38 -
© 2011 ЄУ
Множення матриць в CUDA
int
float
dim3
dim3
numBytes = N * N * sizeof ( float );
* adev, * bdev, * cdev ;
threads ( BLOCK_SIZE, BLOCK_SIZE );
blocks ( N / threads.x, N / threads.y);
cudaMalloc
cudaMalloc
cudaMalloc
( (void**)&adev, numBytes ); // allocate DRAM
( (void**)&bdev, numBytes ); // allocate DRAM
( (void**)&cdev, numBytes ); // allocate DRAM
// copy from CPU to DRAM
cudaMemcpy ( adev, a, numBytes, cudaMemcpyHostToDevice );
cudaMemcpy ( bdev, b, numBytes, cudaMemcpyHostToDevice );
matMult<<<blocks, threads>>> ( adev, bdev, N, cdev );
cudaThreadSynchronize();
cudaMemcpy
( c, cdev, numBytes, cudaMemcpyDeviceToHost );
// free GPU memory
cudaFree
( adev );
cudaFree
( bdev );
cudaFree
( cdev );
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 39 -
© 2011 ЄУ
Актуальні засоби програмування паралельних систем
• MPI (Message Passing Interface, інтерфейс
•
•
передачі повідомлень) - стандарт
програмного інтерфейсу для паралельних систем
із розподіленою пам’яттю (мультикомп’ютери,
кластери).
Open Multi-Processing (OpenMP) - стандарт
програмного інтерфейсу для паралельних систем
із спільною пам'яттю (багатоядерні
системи).
CUDA (Compute Unified Device Architecture)
– програмно-апаратна архітектура, що дозволяє
здійснювати паралельні обчислення з
використанням графічних процесорів NVIDIA.
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 40 -
© 2011 ЄУ
Запитання?
Єршов С.В. Online лекція заняття курсів з підвищення кваліфікації
- 41 -
© 2011 ЄУ