Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

лаб5 / lab5

.pdf
Скачиваний:
11
Добавлен:
27.08.2024
Размер:
585.16 Кб
Скачать

ГУАП КАФЕДРА № 41

ОТЧЕТ ЗАЩИЩЕН С ОЦЕНКОЙ ПРЕПОДАВАТЕЛЬ

Старший преподаватель

Д.В. Куртяник

должность, уч. степень,

подпись, дата инициалы, фамилия

звание

ОТЧЕТ О ЛАБОРАТОРНОЙ РАБОТЕ 5

Параллелизм

по курсу: ОСНОВЫ ПРОГРАММИРОВАНИЯ

РАБОТУ ВЫПОЛНИЛ

 

 

 

 

 

СТУДЕНТ ГР.

4016

 

 

 

М.О.Жовтяк

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

подпись, дата

 

инициалы, фамилия

 

 

Санкт-Петербург 2021

 

 

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

Цель лабораторной работы: изучение автоматического распараллеливания кода, использующего стандартные алгоритмы библиотеки STL, способов применения и особенностей работы; получение навыков программирования на языке C++.

Задание на программирование: разработать программу и провести анализ эффективности работы с использованием различных политик распараллеливания и с использованием автоматического параллелизатора, автоматического векторизатора.

Мой индивидуальный вариант – 17. Сформировать коллекцию L, включив в неё по одному разу элементы, которые входят в коллекцию L1, но не входят в коллекцию L2.

2) Математическая модель решения с указанием подходящих методов решения и алгоритмов из библиотеки STL

В качестве рабочего контейнера был выбран <vector>. Политиками execution

выбраны sequenced_policy (seq), parallel_policy (par), parallel_unseqeunced_policy(par_unseq). В настройках компилятора периодически будут настраиваться автоматическая параллелизация и векторизация.

Будут созданы шаблоны STL:

Заполняющий контейнер случайными числами;

Итерация контейнера;

Шаблон, выполняющий ключевую функцию задачи – заполнение основного контейнера элементами обоих векторов; сортировка всех элементов в нем; удаление повторяющихся элементов и элементов, входящих во второй контейнер.

Задача функции main() заключается в исполнении вызова функции-шаблона, передавая в качестве параметров вектора. Также в этой функции будет выполняться подсчет времени выполнения программы.

Политика параллелизма может быть применена только для функций sort и for_each, которые присутствуют в составленной программе.

Для данной задачи подойдут следующие методы и алгоритмы из библиотеки STL:

unique() – для удаление равных соседних элементов при сохранении первого

из них;

insert(p, x) – для добавления х перед элементом, на который указывает р;

end() – для указания на элемент, который следует за последним;

begin() – указывает на первый элемент;

find – для нахождения итератора на элемент и проверки на его существование;

count – для возвращения количества элементов с заданным значением;

erase – для удаление конкретного элемента.

remove – удаление элемента с определенным значением

for_each – применяет заданный функциональный объект к результату разыменования каждого итератора в диапазоне [first, last)

2

3)Сравнение эффективности выполнения

Числовые значения в ячейках фиксируют время с начала работы программы и измеряются в миллисекундах. Число элементов контейнера для заполнения равно одному миллиону.

 

 

 

 

 

 

 

Без

авто параллелизации и авто векторизации

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Vector

1

Vector 2

 

Vector

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Без политики

2073

 

3965

 

10468

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Политика “par”

 

1845

 

3701

 

 

9263

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Политика “seq”

1980

 

3990

 

11169

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Политика

 

1895

 

3781

 

 

9422

 

 

“par_unseq”

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

С авто параллелизацией

 

 

 

 

 

 

 

 

 

 

 

 

 

Без политики

2132

 

4010

 

10777

 

 

 

 

 

 

 

 

 

 

 

Политика “par”

 

2134

 

4059

 

 

9566

 

 

 

 

 

 

 

 

 

 

 

Политика “seq”

2093

 

3859

 

10671

 

 

 

 

 

 

 

 

 

 

 

 

 

Политика

 

1852

 

3635

 

 

9532

 

 

“par_unseq”

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

С авто векторизацией

 

 

 

 

 

 

 

 

 

 

 

 

 

Без политики

2027

 

4040

 

10744

 

 

 

 

 

 

 

 

 

 

 

Политика “par”

 

1939

 

3995

 

 

9173

 

 

 

 

 

 

 

 

 

 

 

Политика “seq”

2045

 

4272

 

10969

 

 

 

 

 

 

 

 

 

 

 

 

 

Политика

 

1850

 

3627

 

 

9646

 

 

“par_unseq”

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Таблица 1 – Скорость работы при разных настройках компилятора и политиках распараллеливания

Ссылаясь на табл. 1 можно сделать определённые выводы. Зеленым светом подсвечены значения, которые отличаются более быстрой скоростью работы. Скорость заполнения при всех политиках и при всех настройках компилятора примерно равны. Но при политиках “par” и “par_unseq” замечается рост скорости работы примерно на 1 секунду, что составляет сокращение времени работы на примерно 10%. Политика “seq” и без политичное распараллеливание показали худшие результаты. Особенно плохо показала себя политика “seq”, которая работает медленнее, чем при ситуации, когда политики нет. Стоит обратить внимание, что автоматическая параллелизация и векторизация немного, но ускоряют работы последних упомянутых политик.

3

4)Скриншоты работы

На рисунке 1 продемонстрирована работа компилятора с миллионом значений. Вызов функций «showme» закомментирован. Такой способ был использован для сравнения скорости работы при различных политиках распараллеливания и настройках компилятора.

Рисунок 1 – Пример работы программы с миллионом элементов

Рисунок 2 – Демонстрация работы программы с малым количеством элементов

Рисунок 3 – Настройки компилятора

5) Код программы

#include <iostream> #include <vector> #include <algorithm> #include <iterator> #include <ctime> #include <execution>

4

#include <thread> using namespace std;

//заполение вектора

template <typename container>

int filling(container& con, int number)

{

int start = clock();

#pragma loop(hint_parallel(8)); for (int i = 0; i < number; i++)

{

int element = rand() % 1001; con.insert(con.end(), element); element = 0;

}

int end = clock(); return (end - start);

}; //отображение вектора

template <typename container> void showme(container con)

{

cout << "Content of container:";

for_each(con.begin(), con.end(), [](auto a) {std::cout << a << " "; }); std::cout << "completed" << std::endl;

}

//выполнение задачи

template <typename container>

void del(container& con1, container& con2, container& con)

{

vector<int>::iterator it1;

for (it1 = con1.begin(); it1 != con1.end(); ++it1) con.push_back(*it1);

//сортировка и удаление одинаковых элементов коллекции L для более легкого

восприятия

sort(con.begin(), con.end());

auto last1 = unique(con.begin(), con.end()); con.erase(last1, con.end());

//уничтожение элементов L, которые входят в коллекцию L2 for (it1 = con2.begin(); it1 != con2.end(); ++it1)

{

con.erase(remove(con.begin(), con.end(), *it1), con.end());

}

}

int main()

{

int edro = std::thread::hardware_concurrency();

std::cout <<"There are " << edro << " concurrent supported threads.\n"; cout << "Enter number of values for container" << endl;

int number; cin >> number;

vector<int> vect1; vector<int> vect2; vector<int> vect; int time = 0;

time += filling(vect1, number); showme(vect1);

cout << "Spent time for now: " << time << endl; time += filling(vect2, number);

5

showme(vect2);

cout << "Spent time for now: " << time << endl; int start = clock();

del(vect1, vect2, vect); showme(vect);

int end = clock(); time += (end - start);

cout << "Spent time: " << time << endl; cout << endl;

}

Вывод: Политики “par” и “par_unseq” ускорили работу программы, особенно при сортировке элементов при выполнении задачи, остальные не принесли ожидаемых результатов. В ходе работы я познакомился с такими понятиями, как распараллеливания кода, закрепил знания по алгоритмам STL. Также я выяснил, что параллельное выполнение потоков помогает ускорить работу программы за счет распределения ресурсов ядер процессора компьютера, что делает и так быстрый язык С++ более быстрым.

6

Список используемых ресурсов

1)https://pro.guap.ru/get-task/74c98e96d0cef0464bf8271a428c8a14

2)https://docs.microsoft.com/ru-ru/cpp/parallel/auto-parallelization-and-auto- vectorization?view=msvc-160#auto-vectorizer

7

Соседние файлы в папке лаб5