You are on page 1of 6

Міністерство освіти і науки України

Харківський національний університет радіоелектроніки

Факультет КІУ

Кафедра БІТ

Звіт

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

“ОСОБЛИВОСТІ ЕКСПЕРИМЕНТАЛЬНИХ ДОСЛІДЖЕНЬ


ОБЧИСЛЮВАЛЬНОЇ СКЛАДНОСТІ У МУЛЬТИЗАДАЧНОМУ
СЕРЕДОВИЩІ НА ПРИКЛАДІ МЕТОДІВ ФОРМУВАННЯ
МУЛЬТИПЛІКАТИВНО ЗВОРОТНИХ ЕЛЕМЕНТІВ ЗА МОДУЛЕМ”

Рівень складності C

Виконав: Перевірила:

ст.гр. КБІКС-19-3 Мельникова О. А.

Иванов Андрей

Харків 2021
Мета роботи: навчитися проводити експериментальні дослідження
обчислювальної складності у мультизадачному середовищі для операцій з
малою обчислювальною складністю, ознайомитися з методикою усереднення
по мінімальним значенням результатів вимірювань, набути практичних
навичок в реалізації різних методів обчислення мультиплікативно зворотних
елементів за модулем, в тому числі одночасного k-кратного варіанту, та
виконати порівняльний аналіз цих методів, а також отримати додаткову
практику в використанні спеціалізованих бібліотек для обробки
багаторозрядних чисел.

Хід роботи

Рівень складності C (75-82)

Реалізувати метод ланцюгових дробів для обчислення інверсії за довільним


модулем (в тому числі не використовуючи операції копіювання
багаторозрядних чисел), виконати початкове тестування на 3-х тестових
наборах, порівняти за обчислювальною складністю три методи виконання
операції інверсії (бібліотечний, з операціями копіювання та без них),
користуючись методикою усереднення по мінімальним значенням
результатів вимірів, оцінити програмно процентне співвідношення середніх
експериментальних оцінок обчислювальної складності для трьох методів.

Код “Source.cpp”:
#define LIMIT 100
#define COUNT_LIMIT 10
#include <iostream>
#include <windows.h>
#include "MMATH.H"

using namespace std;

int inv(M_LONG e, M_LONG eul, M_LONG d) {


M_LONG a, b, r, s, a_n[3] = { {1, 0}, {1, 1} };
int i = -1;
m_copy(a, eul);
m_copy(b, e);
do {
m_div(a, b, r, s);
m_mul(r, a_n[1], a_n[2]);
m_add(a_n[2], a_n[0], a_n[2]);
++i;
m_copy(a, b);
m_copy(b, s);
m_copy(a_n[0], a_n[1]);
m_copy(a_n[1], a_n[2]);

} while (b[0] != 1 || b[1] != 0);


if (a[0] != 1 || a[1] != 1) return 1;
if (i % 2 == 0) {
m_copy(d, a_n[0]);
return 0;
}
m_sub(eul, a_n[0], d);
return 0;
}

int invOptimized(M_LONG e, M_LONG eul, M_LONG d) {


M_LONG a0, b0, r, s0, a_n0[3] = { {1, 0}, {1, 1} };
DIGIT* a = a0, * b = b0, * s = s0, * tmp, * a_n[3] = { a_n0[0], a_n0[1],
a_n0[2] };

int i = -1;
m_copy(a, eul);
m_copy(b, e);
do {
m_div(a, b, r, s);
m_mul(r, a_n[1], a_n[2]);
m_add(a_n[2], a_n[0], a_n[2]);
++i;
tmp = a;
a = b;
b = s;
s = tmp;
tmp = a_n[0];
a_n[0] = a_n[1];
a_n[1] = a_n[2];
a_n[2] = tmp;
} while (b[0] != 1 || b[1] != 0);
if (a[0] != 1 || a[1] != 1) return 1;
if (i % 2 == 0) {
m_copy(d, a_n[0]);
return 0;
}
m_sub(eul, a_n[0], d);
return 0;
}

int main() {
M_LONG P = { 16,0x6f18544d,0xedb374f5,0xffbc3bcc,0x7249bb52,
0xb09152ec,0x9551dc2c,0x7f6e2853,0xa4dba914,
0xa9bd6e9b,0x70cd54ce,0x31fe7bd3,0xcc61f6d2,
0x5d45c7fc,0x11a20acc,0x39b8708c,0x9df3ef1d },
Q = { 16,0xab74d85d,0x8e352852,0xf440ab72,0x790f53f3,
0xb51fbad0,0x10555a11,0xd79b004c,0x90ca7e6c,
0x8bcca0b1,0xba0262f8,0xc2e3603d,0x52e68e5e,
0xb4a22921,0xa234ee79,0x5ae28905,0xf5fe50db },
E = { 16,0xab74d85d,0x8e352852,0xf440ab72,0x790f53f3,
0xb51fbad0,0x10555a11,0xd79b004c,0x90ca7e6c,
0x8bcca0b1,0xba0262f8,0xc2e3603d,0x52e68e5e,
0xb4a22921,0xa234ee79,0x5ae28905,0xf5fe50db };
M_LONG x, y1, y2, N, d, d1, d2, d3;
int i, res, count;
LARGE_INTEGER t, t1_1, t1_2, t2_1, t2_2, tmin, t3_1, t3_2;
long double t1 = 0, t2 = 0, t3 = 0;
P[1]--;
Q[1] &= 0xFFFFfffE;
m_mul(P, Q, N);
for (count = 0; count < COUNT_LIMIT; count++) {
QueryPerformanceCounter(&t2_1);
inv(E, N, d1);
QueryPerformanceCounter(&t2_2);
t.QuadPart = t2_2.QuadPart - t2_1.QuadPart;
cout << count + 1 << ")\t" << "t = " << t.QuadPart << "\n";
}
cout << endl;
for (count = 0; count < COUNT_LIMIT; count++) {
QueryPerformanceCounter(&t3_1);
invOptimized(E, N, d3);
QueryPerformanceCounter(&t3_2);
t.QuadPart = t3_2.QuadPart - t3_1.QuadPart;
cout << count + 1 << ")\t" << "t = " << t.QuadPart << "\n";
}
cout << endl;
for (count = 0; count < COUNT_LIMIT; count++) {
QueryPerformanceCounter(&t2_1);
m_inv(E, N, d2);
QueryPerformanceCounter(&t2_2);
t.QuadPart = t2_2.QuadPart - t2_1.QuadPart;
cout << count + 1 << ")\t" << "t = " << t.QuadPart << "\n";
}
cout << endl;
int N_limit = 10, N_repetitions = 100;
for (int repetitions = 1; repetitions <= N_repetitions; repetitions += 1) {
t1 = 0;
for (i = 0; i < N_limit; i++) {
tmin.QuadPart = 0x7FFFffffFFFFffff;
for (count = 0; count < repetitions; count++) {
QueryPerformanceCounter(&t1_1);
m_inv(E, N, d);
QueryPerformanceCounter(&t1_2);
t.QuadPart = t1_2.QuadPart - t1_1.QuadPart;
if (t.QuadPart < tmin.QuadPart) tmin.QuadPart = t.QuadPart;
}
t1 += tmin.QuadPart;
}
t1 /= N_limit;
cout << N_limit << " iterations (with " << repetitions << " repetitions):\
t" << t1 << endl;
}
//сравнение
for (i = 0; i < LIMIT; i++) {
tmin.QuadPart = 0x7FFFffffFFFFffff;
for (count = 0; count < COUNT_LIMIT; count++) {
QueryPerformanceCounter(&t1_1);
inv(E, N, d);
QueryPerformanceCounter(&t1_2);
t.QuadPart = t1_2.QuadPart - t1_1.QuadPart;
if (t.QuadPart < tmin.QuadPart) tmin.QuadPart = t.QuadPart;
}
t1 += tmin.QuadPart;

tmin.QuadPart = 0x7FFFffffFFFFffff;
for (count = 0; count < COUNT_LIMIT; count++) {
QueryPerformanceCounter(&t2_1);
m_inv(E, N, d2);
QueryPerformanceCounter(&t2_2);
t.QuadPart = t2_2.QuadPart - t2_1.QuadPart;
if (t.QuadPart < tmin.QuadPart) tmin.QuadPart = t.QuadPart;
}
t2 += tmin.QuadPart;
tmin.QuadPart = 0x7FFFffffFFFFffff;
for (count = 0; count < COUNT_LIMIT; count++) {
QueryPerformanceCounter(&t3_1);
invOptimized(E, N, d3);
QueryPerformanceCounter(&t3_2);
t.QuadPart = t3_2.QuadPart - t3_1.QuadPart;
if (t.QuadPart < tmin.QuadPart) tmin.QuadPart = t.QuadPart;
}
t3 += tmin.QuadPart;

if (m_cmp(d1, d2) || m_cmp(d3, d2)) {


cout << "Error!\n";
return 1;
}
}
t1 /= LIMIT; t2 /= LIMIT; t3 /= LIMIT;
cout << "\nFunction2 = 100% ==> Function1 = " << t2 / t1 * 100 << "%.";
if (t1 > t2) cout << "\nFunction2 function is " << 100 - (t2 / t1 * 100) << "%
faster.\n";
else cout << "\nFunction1 is " << 100 - (t1 / t2 * 100) << "% faster.\n";
cout << "\nFunction2 = 100% ==> Function3 = " << t2 / t3 * 100 << "%.";
if (t3 > t2) cout << "\nFunction2 is " << 100 - (t2 / t3 * 100) << "% faster.\n";
else cout << "\nFunction3 is " << 100 - (t3 / t2 * 100) << "% faster.\n";
return 0;
}

Результат роботи програми:


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

You might also like