Celem prac wykonanych na laboratoriach byo zapoznanie si z metodami optymalizacji pracy
programw uwzgldniajcej fizyczn architektur komputera. Na podstawie dostarczonego projektu rodowiska Microsoft Visual Studio dokonywaem modyfikacji funkcji odpowiadajcej za wykonywanie mnoenia macierzy przez wektor (oba obiekty znajdoway si w pamici RAM) i sprawdzaem wpyw wprowadzonych zmian na szybko dziaania programu. Pierwsz wprowadzon przez mnie modyfikacj bya zmiana gwnej ptli funkcji liczcej w taki sposb, aby program odczytywa kolejne (wystpujce obok siebie w pamici RAM) wartoci, a nie tak jak byo to w poprzedniej wersji funkcji dokonywa skokw kolejne wywoywane z pamici operacyjnej liczby nie znajdoway si obok siebie. Kolejnym zastosowanym ulepszeniem byo wprowadzenie do ptli wikszej iloci operacji i zwikszenie skokw ptli o 4. Dziki temu w trakcie jednej iteracji ptli wykonywane byy obliczenia na 4 liczba, co pozwolio procesorowi na sprawniejsze wykorzystanie potokw rwnolegego wykonywania rnych fragmentw operacji zwizanej z wykonywaniem przez procesor polece. Trzecia optymalizacja polegaa na zamianie zwykych zmiennych na rejestry xmm. Jeden rejestr moe jednoczenie pobra do pamici nie jedn, a dwie liczby i rwnie rwnolegle wykonywa obliczenia. Ponadto korzystanie z rejestrw pozwala zastosowa funkcje _mm_prefetch, ktra informuje o procesor o tym, e naley zaczyta jaki obszar danych i pozostawi go w pamici podrcznej, gdy dane bd w najbliszym czasie uywane. Poniszy screen przedstawia pomiary czasu pracy funkcji, po kolejnych optymalizacjach:
W pierwszym wiczeniu macie bya uoona w pamici operacyjnej kolumnami. W drugi za
zadaniu macie uoona bya w pamici wierszami, a poleceniem, ktre miaem wykona byo przygotowanie zoptymalizowanej operacji mnoenia z wykorzystanie wszystkich opisanych powyej technik. Poniszy screen przedstawia wyniki pomiarw:
Wszystkie pomiary zostay wykonanie na procesorze Intel i5 4670
Kod przygotowanej przeze mnie funkcji z wiczenia nr 2 wyglda nastpujco: void matvec_XMM(double* a, double* x, double* y, int n, int lb) { //napisz swoj kod int i, j, ij = 0,rest; __m128d ra3, ra2, ra1, ra0, rx0, rx1, rx2, rx3; _declspec(align(16)) double res[8]; double *ptr_a, *ptr_x; ptr_a = a; ptr_x = x; for (i = 0; i { y[i] = rest = for (j
< n; i += 1) 0; n % 8; = 0; j<rest; ++j, ++ij) y[i] += a[ij] * x[j];