You are on page 1of 10

ХАРКІВСЬКИЙ НАЦІОНАЛЬНИЙ

УНІВЕРСИТЕТ РАДІОЕЛЕКТРОНИКИ
Кафедра «Програмної інженерії»

ЗВІТ

з лабораторної роботи № 1

з дисципліни «Паралельне програмування»

Виконали:
Студенти групи ПЗПІ-20-5
Середа Ілля Перевірила ст. викладач
Вожова Маргарита каф. ПІ Олійник О. В.

Харків 2022
Тема роботи:
Методи визначення обчислювальної складності програм
Мета роботи:

Для порівняння програм по обчислювальній складності треба вміти


визначати цю складність. Метою даної роботи є придбання практичних навиків
визначення обчислювальної складності алгоритму та програми, а також вплив
розміру масивів, типів даних, режимів компіляції програм на обчислювальну
складність при послідовному виконанні алгоритму.

Хід роботи:

1) Для функції time визначте дату останнього використання 32 бітного


часу5. Для цього, наприклад, перетворіть час 0x7FFFFFFF в форматі time_t в
формат SystemTime.

Для цього ми використовуємо функцію strftime, яка конвертує час у


строку за заданими настройками локалі:

Результат:
2) Експериментально визначте точність обчислення часу при використанні
функцій з табл. 1.16 . Запишіть отримані результати в табл. 1.1.

Функція Файл Результат Точність


заголовків
Time Time.h Секунди 1
Clock Time.h Міллісекунди 1
GetSystemTimeAsFileTime Windows.h Такти 9970
GetSystemTimePreciseAsFileTime Windows.h Міллісекунди 2
GetTickCount Windows.h Такти 15
__rdtsc Intrin.h Такти 40
QueryPerformanceCounter Windows.h Визначається функцією 1e-07
QueryPerformanceFrequency
class chrono chrono Наносекунди 6e-07
omp_get_wtime Omp.h Секунди 3.00002e-07
Таблиця 1.1 Функції для виміру часу виконання фрагменту програми

Код:
__int64 to_int64(FILETIME ft)
{
return static_cast<__int64>(ft.dwHighDateTime) << 32 | ft.dwLowDateTime;
}

void Task2Time()
{
time_t start = time(0);
//Цикл работает пока между стартом и концом не будет разницы
while (start == time(0)) {
}
cout << "Точность функции Time в секундах: " << time(0) - start << endl;
}

void Task2Clock()
{
clock_t start = clock();
//Цикл работает пока между стартом и концом не будет разницы
while (start == clock()) {
}

cout << "Точность функции Clock в миллисекундах: " << clock() - start << endl;
}

void Task2GetSystemTimeAsFileTime()
{
FILETIME fileTimeStart, fileTimeEnd;
GetSystemTimeAsFileTime(&fileTimeStart);
GetSystemTimeAsFileTime(&fileTimeEnd);
//Цикл работает пока между стартом и концом не будет разницы
while (fileTimeStart.dwLowDateTime == fileTimeEnd.dwLowDateTime)
{
GetSystemTimeAsFileTime(&fileTimeEnd);
}
cout << "Точность функции GetSystemTimeAsFileTime в тактах: "
<< (to_int64(fileTimeEnd) - to_int64(fileTimeStart)) << endl;
}

void Task2GetSystemTimePreciseAsFileTime()
{
FILETIME fileTimeStart, fileTimeEnd;
GetSystemTimePreciseAsFileTime(&fileTimeStart);
GetSystemTimePreciseAsFileTime(&fileTimeEnd);
//Цикл работает пока между стартом и концом не будет разницы
while (fileTimeStart.dwLowDateTime == fileTimeEnd.dwLowDateTime)
{
GetSystemTimePreciseAsFileTime(&fileTimeEnd);
}
cout << "Точность функции GetSystemTimePreciseAsFileTime в миллисекундах: "
<< (to_int64(fileTimeEnd) - to_int64(fileTimeStart)) << endl;
}

void Task2GetTickCount()
{
DWORD start = GetTickCount64();
//Цикл работает пока между стартом и концом не будет разницы
while (start == GetTickCount64()) {
}

cout << "Точность функции GetTickCount64 в тактах: "


<< (GetTickCount64() - start) << endl;
}

void Task2__rdtsc()
{
unsigned _int64 start = __rdtsc();
//Цикл работает пока между стартом и концом не будет разницы
while (start == __rdtsc()) {
}

cout << "Точность функции __rdtsc в тактах: "


<< (__rdtsc() - start) << endl;
}

void Task2QueryPerformanceCounter()
{
LARGE_INTEGER start, end;
QueryPerformanceCounter(&start);
QueryPerformanceCounter(&end);
//Цикл работает пока между стартом и концом не будет разницы
while (start.QuadPart == end.QuadPart) {
QueryPerformanceCounter(&end);
}
cout << "Точность функции QueryPerformanceCounter: "
<< (end.QuadPart - start.QuadPart) << endl;

void Task2Chrono()
{
high_resolution_clock::time_point start = high_resolution_clock::now();
duration<double> accuracy;
start = high_resolution_clock::now();
while (start == high_resolution_clock::now()) {

}
accuracy = duration_cast<duration<double>>(high_resolution_clock::now() - start);
cout << "Точность chrono в наносекундах: " << accuracy.count() << endl;
}

void Task2Omp_get_wtime()
{
double start = omp_get_wtime();
//Цикл работает пока между стартом и концом не будет разницы
while (start == omp_get_wtime()) {
}

cout << "Точность omp_get_wtime в секундах: " << omp_get_wtime() - start << endl;
}

Результат:

3) Перевірте використання функцій __rdtsc та QueryPerformanceCounter


для визначення часу додавання масиву чисел розміром 1000 елементів.
Порівняйте результати.
Результат:

При використанні функції QueryPerfomanceCounter розрахунок швидкості


програми є найбільш точним.
4) Для задачі додавання масиву чисел розміром 100000, 200000, 300000
елементів використайте абсолютний та відносний вимір часу. Для абсолютного
виміру використовувати функцію omp_get_wtime. Для відносного визначте
кількість циклів додавання , які можна виконати за 2 с для кожного розміру.
Вимір виконувати функцією GetTickCount. Порівняйте відношення часу
T(200000)/T (100000), T(300000)/T (100000) для обох методів. Зробить висновки
по можливості використання відносного виміру часу.

Результат:
5) Складіть функції для обчислення множення для 2-х квадратних
матриць. Перша функція не використовує об’єкти, інша використовує.

Код функції з об’єктами:

Код функції без об’єктів:

Код функції MultiplyMatrices:


6) Визначте формулу для обчислення O(n).

Через те, що функція перемноження використовує три вкладених цикли, її


формула складності буде O(n) = n3

7) Перевірте експериментально цю формулу для різних n у разі


невикористання та використання об’єктів. Поясніть отримані результати для
матриць розміром 512, 1024, 2048.

Результат:

8) Задайте режим Release при виконаннії додатків і виконайте попередній


пункт. Поясніть отримані результати.

Використовуючи режим Release, функції будуть працювати швидше через


те, що цей режим призначений для оптимізації кода, що дозволить коду швидше
виконуватись:

9) Дослідить вплив типу даних (int8, int16, int32, __int64, float, double) для
розміру матриць n = 1024. Отримані результати занести в таблицю. Зробіть
висновки по впливу типу даних.
Тип данных Размер Время, с
int8 1024 0.563275
int16 1024 0.58569
int32 1024 0.659718
_int64 1024 1.08995
float 1024 0.644701
double 1024 0.910367

Результат:

Висновок: На даній лабораторній роботі навчилися порівнювати програми


завдяки визначенню складності. Навчилися визначати обчислювальну
складність алгоритму та програми, а також вплив розміру масивів, типів даних,
режимів компіляції програм на обчислювальну складність при послідовному
виконанні алгоритму.

You might also like