Добавил:
Кафедра ВТ Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2 лаба / lab2.docx
Скачиваний:
5
Добавлен:
07.04.2023
Размер:
749.33 Кб
Скачать

3. Оптимизация кода с помощью openmp

Перепишем функцию под openmp.

float calc_pi(unsigned N_iters) { const float N_f = (float)N_iters; float pi = 0.0; #pragma omp parallel { unsigned th_n = omp_get_num_threads(); unsigned th_i = omp_get_thread_num(); unsigned iter_per_th = N_iters / th_n; unsigned lb = iter_per_th*th_i; unsigned ub = 5051; if(th_i == th_n-1) ub = N_iters-1; else ub = lb + iter_per_th-1; float pi_local = 0.0; ALIGNED_(32) float vres[8]; __m256 onem = _mm256_set1_ps(1.0); __m256 Nm = _mm256_set1_ps(N_f); __m256 buffm; for(unsigned i = lb; i <= ub; i+=8) { float j = (float)i + 0.5; buffm = _mm256_set_ps(j, j+1.0, j+2.0, j+3.0, j+4.0, j+5.0, j+6.0, j+7.0); buffm = _mm256_div_ps(buffm, Nm); buffm = _mm256_mul_ps(buffm, buffm); buffm = _mm256_add_ps(buffm, onem); buffm = _mm256_div_ps(onem, buffm); buffm = _mm256_hadd_ps(buffm, buffm); buffm = _mm256_hadd_ps(buffm, buffm); _mm256_store_ps(vres, buffm); pi_local += vres[0] + vres[7]; } #pragma omp atomic pi += pi_local; } pi *= 4.0; pi /= N_iters; return pi; }

Компилируем:

> CC lab1_3.c -o lab1_3 -O0 -Wall -mavx2 -fopenmp

Исходный код программы lab1_3.c представлен в приложении.

Сделаем замеры:

> ./lab1_3 # CLANG: # CPU time spent: 64.541564 sec (64541564 us) # Real time spent: 10.787499 sec (10787499 us) # GCC: # CPU time spent: 56.361458 sec (56361458 us) # Real time spent: 9.429584 sec (9429584 us)

При замерах не были запущены какие-либо другие приложения и программы.

> perf stat -B -e task-clock,context-switches,cpu-migrations,cycles,instructions,cache-references,cache-misses,branches,branch-misses,migrations,page-faults ./lab1_3 # Performance counter stats for './lab1_3': CLANG # 64 717,34 msec task-clock:u # 5,991 CPUs utilized # 0 context-switches:u # 0,000 /sec # 0 cpu-migrations:u # 0,000 /sec # 251 040 117 627 cycles:u # 3,879 GHz # 149 517 410 100 instructions:u # 0,60 insn per cycle # 2 372 767 cache-references:u # 36,664 K/sec # 64 480 cache-misses:u # 2,718 % of all cache refs # 2 742 245 558 branches:u # 42,373 M/sec # 184 774 branch-misses:u # 0,01% of all branches # 0 migrations:u # 0,000 /sec # 228 page-faults:u # 3,523 /sec # Performance counter stats for './lab1_3': GCC # 57 339,27 msec task-clock:u # 5,955 CPUs utilized # 0 context-switches:u # 0,000 /sec # 0 cpu-migrations:u # 0,000 /sec # 222 462 812 833 cycles:u # 3,880 GHz # 146 487 026 305 instructions:u # 0,66 insn per cycle # 1 515 921 cache-references:u # 26,438 K/sec # 45 507 cache-misses:u # 3,002 % of all cache refs # 5 063 664 678 branches:u # 88,311 M/sec # 53 451 branch-misses:u # 0,00% of all branches # 0 migrations:u # 0,000 /sec # 85 page-faults:u # 1,482 /sec

Сведём в таблицу:

время

IPC

cache-misses

gcc

9.4

0,66

3

clang

10.8

0,60

2,7

Сделаем таблицу замера времени в зависимости от кол-ва потоков. На i5-9400F 6 физических потоков и 6 логических потоков.

потоки

1

2

4

6

8

12

время

54.6

27.3

14.1

9.4

14.0

11

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