Новости
О Центре
Кластер
Обучение
Основной курс по параллельному программированию
Учебные курсы
Магистратура
Дополнительное образование
Работы студентов
Библиотека
Исследования
Конференции
Полезные ссылки
NVIDIA
Контакты
О сайте
Имя:
Пароль:
запомнить:
Забыли пароль? Регистрация

Постановка задачи

В ходе лабораторной работы необходимо: 1. Выполнить реализацию алгоритма параллельной сортировки слиянием 2. Выполнить реализацию алгоритма последовательной сортировки слиянием 3. Рассчитать теоретическое ускорение и эффективность 4. Провести эксперименты и сравнить ускорение параллельной и последовательной версии.

Последовательная версия

Описание алгоритма

1. Получение размера сортируемого массива

2. Заполнение массива

3. Вызов рекурсивной процедуры сортировки.

Реализация

Функция, задающая рекурсию:

long split;

if (lb < ub) {

split = (lb + ub)/2;

mergeSort(a, lb, split);
mergeSort(a, split+1, ub);
merge(a, lb, split, ub);
}
Слияние:
long pos1=lb;

long pos2=split+1;

long pos3=0;

int *temp = new int[ub-lb+1];

while (pos1 <= split && pos2 <= ub)
{
if (a[pos1] < a[pos2])
temp[pos3++] = a[pos1++];
else
temp[pos3++] = a[pos2++];
}

while (pos2 <= ub)
temp[pos3++] = a[pos2++];
while (pos1 <= split)
temp[pos3++] = a[pos1++];

for (pos3 = 0; pos3 < ub-lb+1; pos3++)
a[lb+pos3] = temp[pos3];

delete[] temp;
Анализ эффективности
n – количество элементов
T(n) = n * log2n

Параллельная версия

Реализация параллельной сортировки слиянием была выполнена с помощью MPI.

Описание алгоритма
1. Получение размера сортируемого массива
2. Заполнение массива
3. Распределение массива по всем процессорам
4. Сортировка блока на каждом процессоре
5. Слияние блоков происходит в виде дерева

Реализация алгоритма

Распределение данных:

if(processorId == 0)
{
data = new int[sizeOfData];

for(int i=0; i data[i] = rand();

localData = new int[sizeOfLocalData];

for(int i=0; i localData[i] = data[i];

for(int i=1; i MPI_Send(&data[i*sizeOfLocalData], sizeOfLocalData, MPI_INT, i, 0, MPI_COMM_WORLD);

StartCounter();
}
else
{
localData = new int[sizeOfLocalData];

MPI_Recv(localData, sizeOfLocalData, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
}

MPI_Barrier(MPI_COMM_WORLD);

Слияние блоков:

n = log2(numOfProcessors) + 1;
int step = 1;

for(int i=0; i {
if((processorId % step) == 0)
{
if(and(processorId, simpleMask(i)) == 0)
{
int *tempData = new int[sizeOfLocalData];
int *commonTempData = new int[2*sizeOfLocalData];

MPI_Recv(tempData, sizeOfLocalData, MPI_INT, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &status);

int l=0;
int r=0;

while((l {
if(localData[l] < tempData[r])
{
commonTempData[l+r] = localData[l];
l++;
}
else
{
commonTempData[l+r] = tempData[r];
r++;
}
}

while(l {
commonTempData[l+r] = localData[l];
l++;
}

while(r {
commonTempData[l+r] = tempData[r];
r++;
}

delete[] localData;
delete[] tempData;

sizeOfLocalData = sizeOfLocalData * 2;

localData = new int[sizeOfLocalData];

for(int j=0; j localData[j] = commonTempData[j]
;
delete[] commonTempData;
}
else
{
int dist = processorId - simpleMask(i);

MPI_Send(localData, sizeOfLocalData, MPI_INT, dist, 0, MPI_COMM_WORLD);
}

step = step * 2;
}

MPI_Barrier(MPI_COMM_WORLD);
}

Анализ эффективности

p – количество процессоров, n – количество элементов в исходном массиве.
Сортировка каждого блока:
T1(n) = C1 * (n/p) * log2(n/p)
Слияние блоков:
T2(n) = C2 * p * (2n/p) = C2 * 2 * n
В сумме получаем:
T(n) = T1(n) + T2(n) = (n/p) * (C1 * log2(n/p) + C2 * 2log2p – 1)
Ускорение:
Sтеор = n * log2n / (C1 * (n/p) * log2(n/p) + C2 * 2 * n)

Эксперименты

Эксперименты проводились на машине со следующими характеристиками: Intel Core i5, 3 Гб ОП, Windows 7. Время измеряется в милисекундах.

Размер матрицы

Последовательный алгоритм

Параллельный алгоритм (2 процесса)

Ускорение реальное

Ускорение теоретическое

Параллельный алгоритм (4 процесса)

Ускорение реальное

Ускорение теоретическое

100

40

212

0.188

0.984

1338

0.29

1.287

1000

430

396

1.085

1.182

1476

0.291

1.663

5000

2446

631

3.876

1.289

1833

1.334

1.869

10000

5186

1177

4.406

1.309

1937

2.667

1.947

50000

32573

3836

8.491

1.38

6962

4.678

2.108

100000

61842

7734

7.996

1.407

12226

5.058

2.17

200000

122771

16380

7.495

1.431

23489

5.226

2.228

Об авторах

Работу выполнил студент группы 8303 Коклюев Сергей

Новости

22.10.2012
04.09.2012
05.04.2012
06.03.2012
02.03.2012