Інформація про навчальний заклад

ВУЗ:
Інші
Інститут:
Не вказано
Факультет:
КН
Кафедра:
Кафедра ЕОМ

Інформація про роботу

Рік:
2024
Тип роботи:
Звіт до лабораторної роботи
Предмет:
Алгоритми та методи обчислень

Частина тексту файла (без зображень, графіків і формул):

Кафедра ЕОМ Звіт з лабораторної роботи № 3 з дисципліни: “Алгоритми та методи обчислень” Варіант № 7 Мета роботи: ознайомитися з використанням потокового графу алгоритму при паралельному програмуванні Вхідні дані с = 565 b = 566 a = 561 Лістинг програми: #include <stdio.h> #include <stdlib.h> #include <x86intrin.h> // Linux #include <math.h> #include <time.h> #define A 565  #define B 566  #define C 561   #pragma GCC push_options #pragma GCC optimize ("no-unroll-loops") #define REPEAT_COUNT 1000000 #define REPEATOR(count, code) \ for (unsigned int indexIteration = (count); indexIteration--;){ code; } #define TWO_VALUES_SELECTOR(variable, firstValue, secondValue) \ (variable) = indexIteration % 2 ? (firstValue) : (secondValue); double getCurrentTime(){ clock_t time = clock(); if (time != (clock_t)-1) { return ((double)time / (double)CLOCKS_PER_SEC); } return 0.; // else } #pragma GCC push_options #pragma GCC target ("no-sse2") // attribute (( target ("no-sse2"))) void run_native(double * const dArr){ double * const dAC = dArr; double * const dA = &dAC[0]; double * const dC = &dAC[1]; double * const dB = &dArr[2]; double * const dResult = &dArr[4]; double * const dX1 = &dResult[1]; double * const dX2 = &dResult[0]; REPEATOR(REPEAT_COUNT, TWO_VALUES_SELECTOR(*dA, 4., A); TWO_VALUES_SELECTOR(*dB, 3., B); TWO_VALUES_SELECTOR(*dC, 1., C); double vD = sqrt((*dB)*(*dB) - 4.*(*dA)*(*dC)); (*dX1) = (-(*dB) + vD) / (2.*(*dA)); (*dX2) = (-(*dB) - vD) / (2.*(*dA)); ) } #pragma GCC pop_options void run_SSE2(double * const dArr){ double * const dAC = dArr; double * const dA = &dAC[0]; double * const dC = &dAC[1]; double * const dB = &dArr[2]; double * const dResult = &dArr[4]; double * const dX1 = &dResult[1]; double * const dX2 = &dResult[0]; m128d r zero_zero, r c_a, r uORb_b, r 2cORbOR2a_2a, r zero_bb, r sqrtDiscriminant_zero, r_result; r zero_zero = _mm_set_pd(0., 0.); // init REPEATOR(REPEAT_COUNT, TWO_VALUES_SELECTOR(*dA, 4., A); TWO_VALUES_SELECTOR(*dB, 3., B); TWO_VALUES_SELECTOR(*dC, 1., C); r c_a = _mm_load_pd(dAC); // r uORb_b = _mm_load_pd1(dB); r uORb_b = _mm_load1_pd(dB); // b b r uORb_b = _mm_unpacklo_pd(r uORb_b, r uORb_b); // (etap 1) r 2cORbOR2a_2a = _mm_add_pd(r c_a, r c_a); // b 2c r_result = _mm_unpackhi_pd(r 2cORbOR2a_2a, r uORb_b); // b 2a r 2cORbOR2a_2a = _mm_unpacklo_pd(r 2cORbOR2a_2a, r uORb_b); // bb 4ac (etap 2) r_result = _mm_mul_pd(r_result, r 2cORbOR2a_2a); r zero_bb = _mm_unpackhi_pd(r_result, r zero_zero); // zero Discriminant (etap 3) r_result = _mm_sub_sd(r zero_bb, r_result); // zero sqrtDiscriminant (etap 4) r_result = _mm_sqrt_sd(r_result, r_result); r sqrtDiscriminant_zero = _mm_shuffle_pd(r_result, r_result, 1); // sqrtDiscriminant -sqrtDiscriminant (etap 5) r_result = _mm_sub_sd(r sqrtDiscriminant_zero, r_result); // (etap 6) r_result = _mm_sub_pd(r_result, r uORb_b); // 2a 2a r 2cORbOR2a_2a = _mm_unpacklo_pd(r 2cORbOR2a_2a, r 2cORbOR2a_2a); // (etap 7) r_result = _mm_div_pd(r_result, r 2cORbOR2a_2a); _mm_store_pd(dResult, r_result); ) } void printResult(char * const title, double * const dArr, unsigned int runTime){ double * const dAC = dArr; double * const dA = &dAC[0]; double * const dC = &dAC[1]; double * const dB = &dArr[2]; double * const dResult = &dArr[4]; double * const dX1 = &dResult[1]; double * const dX2 = &dResult[0]; printf("%s:\r\n", title); printf("%fx^2 + %fx + %f = 0;\r\n", *dA, *dB, *dC); printf("x1 = %1.0f; x2 = %1.0f;\r\n", *dX1, *dX2); printf("run time: %dns\r\n\r\n", runTime); } int main() { double * const dArr = (double *)_mm_malloc(6 * sizeof(double), 16); double * const dAC = dArr; double * const dA = &dAC[0]; double * const dC = &dAC[1]; double * const dB = &dArr[2]; double * const dResult = &dArr[4]; double * const dX1 = &dResult[1]; double * const dX2 = &dResult[0]; double startTime, endTime; // native (only x86, if auto vectorization by compiler is off) startTime = getCurrentTime(); run_native(dArr); endTime = getCurrentTime(); printResult("x86", dArr, (unsigned int)((endTime - startTime) * (1000000000 / REPEAT_COUNT))); // SSE2 startTime = getCurrentTime(); run_SSE2(dArr); endTime = getCurrentTime(); printResult("SSE2", dArr, (unsigned int)((endTime - startTime) * (1000000000 / REPEAT_COUNT))); _mm_free(dArr); printf("Press any key to continue . . ."); getchar(); return 0; } #pragma GCC pop_options Скріншот виконання програми: / Висновок - ознайомився з використанням потокового графу
Антиботан аватар за замовчуванням

14.10.2018 19:10-

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!