Optymalizacja kodu. Ze wszystkich metod optymalizacji kodu programowego zwrócimy uwagę na: Usunięcie (po możliwości) skoków danych.



Podobne dokumenty
Podstawy Programowania C++

Struktura programu. Projekty złożone składają się zwykłe z różnych plików. Zawartość każdego pliku programista wyznacza zgodnie z jego przeznaczeniem.

Przygotowanie kilku wersji kodu zgodnie z wymogami wersji zadania,

1 Podstawy c++ w pigułce.

Zrównoleglenie i przetwarzanie potokowe

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

Tablice. Monika Wrzosek (IM UG) Podstawy Programowania 96 / 119

Wymiar musi być wyrażeniem stałym typu całkowitego, tzn. takim, które może obliczyć kompilator. Przykłady:

Kompilator języka C na procesor 8051 RC51 implementacja

Pętle i tablice. Spotkanie 3. Pętle: for, while, do while. Tablice. Przykłady

1 Podstawy c++ w pigułce.

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Wykład VII. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik

- - Ocena wykonaniu zad3. Brak zad3

Strona główna. Strona tytułowa. Programowanie. Spis treści. Sobera Jolanta Strona 1 z 26. Powrót. Full Screen. Zamknij.

Wprowadzenie w dziedziczenie. Klasa D dziedziczy klasę B: Klasa B klasa bazowa (base class), klasa D klasa pochodna (derived class).

Programowanie w C++ Wykład 2. Katarzyna Grzelak. 4 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 44

Wykład 8: klasy cz. 4

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów

Niezwykłe tablice Poznane typy danych pozwalają przechowywać pojedyncze liczby. Dzięki tablicom zgromadzimy wiele wartości w jednym miejscu.

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy WSKAŹNIKI KLASOWE

1 P roste e t ypy p d a d n a ych c - c ąg ą g d a d l a szy 2 T y T py p z ł z o ł żo ż ne e d a d n a ych c : T BLICE

Wstęp do programowania

LABORATORIUM 3 ALGORYTMY OBLICZENIOWE W ELEKTRONICE I TELEKOMUNIKACJI. Wprowadzenie do środowiska Matlab

Podstawy programowania. Wykład Pętle. Tablice. Krzysztof Banaś Podstawy programowania 1

6. Pętle while. Przykłady

Tablice, funkcje - wprowadzenie

Podstawy programowania skrót z wykładów:

Podstawy programowania. Wykład: 5. Instrukcje sterujące c.d. Stałe, Typy zmiennych c.d. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Programowanie obiektowe. Dr hab. Inż. Marta Gładysiewicz-Kudrawiec Pokój 229 A1 Operatory new delete pliki-odczyt

PROE wykład 2 operacje na wskaźnikach. dr inż. Jacek Naruniec

Języki C i C++ Wykład: 2. Wstęp Instrukcje sterujące. dr Artur Bartoszewski - Języki C i C++, sem. 1I- WYKŁAD

Tworzenie programów równoległych cd. Krzysztof Banaś Obliczenia równoległe 1

Functionalization. Funkcje w C. Marcin Makowski. 30 listopada Zak lad Chemii Teoretycznej UJ

Architektura potokowa RISC

Algorytmy równoległe. Rafał Walkowiak Politechnika Poznańska Studia inżynierskie Informatyka 2010

Programowanie w C++ Wykład 2. Katarzyna Grzelak. 5 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 41

Architektura komputerów

PROE wykład 3 klasa string, przeciążanie funkcji, operatory. dr inż. Jacek Naruniec

Spis treści. I. Skuteczne. Od autora... Obliczenia inżynierskie i naukowe... Ostrzeżenia...XVII

Przeciążenie operatorów

INFORMATYKA Studia Niestacjonarne Elektrotechnika

Metody Metody, parametry, zwracanie wartości

W2 Wprowadzenie do klas C++ Klasa najważniejsze pojęcie C++. To jest mechanizm do tworzenia obiektów. Deklaracje klasy :

Podstawy programowania. Wykład 6 Wskaźniki. Krzysztof Banaś Podstawy programowania 1

Wstęp do programowania INP003203L rok akademicki 2018/19 semestr zimowy. Laboratorium 2. Karol Tarnowski A-1 p.

Lab 9 Podstawy Programowania

Ćwiczenie 1. Wprowadzenie do programu Octave

Podstawy informatyki. Informatyka stosowana - studia niestacjonarne. Grzegorz Smyk

Architektura komputerów

Wydajność programów sekwencyjnych. Krzysztof Banaś Obliczenia Wysokiej Wydajności 1

Przetwarzanie potokowe pipelining

Podstawy programowania. Wykład: 9. Łańcuchy znaków. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Część XV C++ Ćwiczenie 1

1 Wskaźniki i zmienne dynamiczne, instrukcja przed zajęciami

Spis treści WSKAŹNIKI. DYNAMICZNY PRZYDZIAŁ PAMIĘCI W JĘZYKU C. Informatyka 2. Instrukcja do pracowni specjalistycznej z przedmiotu

Podstawy programowania C. dr. Krystyna Łapin

7. Pętle for. Przykłady

Struktury. Przykład W8_1

Zaawansowane programowanie w C++ (PCP)

PLAN WYNIKOWY PROGRAMOWANIE APLIKACJI INTERNETOWYCH. KL IV TI 6 godziny tygodniowo (6x15 tygodni =90 godzin ),

Przykładem jest komputer z procesorem 4 rdzeniowym dostępny w laboratorium W skład projektu wchodzi:

Wykład 1_2 Algorytmy sortowania tablic Sortowanie bąbelkowe

ANALIZA EFEKTYWNOŚCI MNOŻENIA MACIERZY W SYSTEMACH Z PAMIĘCIĄ WSPÓŁDZIELONĄ

Wydajność obliczeń a architektura procesorów. Krzysztof Banaś Obliczenia Wysokiej Wydajności 1

Język programowania DELPHI / Andrzej Marciniak. Poznań, Spis treści

Co to jest sterta? Sterta (ang. heap) to obszar pamięci udostępniany przez system operacyjny wszystkim działającym programom (procesom).

Techniki Optymalizacji: Stochastyczny spadek wzdłuż gradientu I

Podstawy programowania. Wykład 7 Tablice wielowymiarowe, SOA, AOS, itp. Krzysztof Banaś Podstawy programowania 1

Tablice mgr Tomasz Xięski, Instytut Informatyki, Uniwersytet Śląski Katowice, 2011

Tablice i funkcje. Marcin Makowski. 26 listopada Zak lad Chemii Teoretycznej UJ

Wstęp do programowania INP001213Wcl rok akademicki 2018/19 semestr zimowy. Wykład 4. Karol Tarnowski A-1 p.

1. Liczby i w zapisie zmiennoprzecinkowym przedstawia się następująco

Energooszczędne programowanie

Zapisywanie algorytmów w języku programowania

Zaprojektować i zaimplementować algorytm realizujący następujące zadanie.

Programowanie obiektowe, wykład nr 7. Przegląd typów strukturalnych - klasy i obiekty - c.d.

Optymalizacja ciągła

Programowanie w języku C++ Grażyna Koba

Procesy i wątki. Krzysztof Banaś Obliczenia równoległe 1

Obliczenie pola wieloboku na podstawie współrzędnych wierzchołków

W dowolnym momencie można zmienić typ wskaźnika.

Programowanie procesorów graficznych GPGPU

for (i=0; i<10; i=i+1) instrukcja; instrukcja zostanie wykonana 10 razy for (inicjalizacja; test; aktualizacja) instrukcja;

Dr inż. Grażyna KRUPIŃSKA. D-10 pokój 227 WYKŁAD 7 WSTĘP DO INFORMATYKI

Przekazywanie argumentów wskaźniki

Jeśli chcesz łatwo i szybko opanować podstawy C++, sięgnij po tę książkę.

Programowanie Strukturalne i Obiektowe Słownik podstawowych pojęć 1 z 5 Opracował Jan T. Biernat

*W uproszczeniu: jest dziewięciu sędziów przyznających po dwie noty: za wartość techniczną i artystyczną (skala od 0.0 do 6.0)

Administracja i programowanie pod Microsoft SQL Server 2000

Szablony klas, zastosowanie szablonów w programach

Pętla for. Wynik działania programu:

Programowanie w języku C++

Programowanie obiektowe. Literatura: Autor: dr inŝ. Zofia Kruczkiewicz

Programowanie współbieżne... (10) Andrzej Baran 2010/11

Programowanie w elektronice: Podstawy C

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

Programowanie - wykład 4

Poradnik programowania procesorów AVR na przykładzie ATMEGA8

Transkrypt:

Optymalizacja kodu Ze wszystkich metod optymalizacji kodu programowego zwrócimy uwagę na: Usunięcie (po możliwości) skoków danych Rozwijanie pętli Opcje kompilatora 1

Usunięcie skoków danych: for(i=1; i<=n; i++) for(j=1; j<=n; j++) ij = N*(j-1)+i; A[ij] =.. Ten fragment kodu będzie wykonany bardzo wolno, dla tego że elementy dużej tablicy są pobierane z pamięci nie ciągłe. To powoduje N 2 odczytów stron pamięci, przy czym z każdej strony będzie pobrane tylko jedno słowo (zakładamy, że N > M, gdzie M ilość słów, które można umieścić w stronie pamięci głównej). 1 2 A = 3 : N N + 1 N + 2 N + 3 : 2N 2N 2N 2N : 3N + 1 + 2 + 3 : : : : : ( N 1) N + 1 ( N 1) N + 2 ( N 1) N + 3 : 2 N Taki fragment kodu jest zdecydowanie lepiej: for(j=1, ij = 0; j<=n; j++) for(i=1; i<=n; i++, ij++) A[ij] =.. Teraz elementy tablicy A będą pobierane z pamięci ciągłe, przy odczycie każdej strony będą użyte wszystkie słowa, znajdujące się w stronie, i tylko po tym będzie odczyt nowej strony. Ilość odczytów stron: N 2 /M << N 2. 2

Rozwijanie pętli potoki procesora nie w stanie zacząć opracowywać instrukcji z następnej iteracji dotąd, dokąd nie skończą instrukcji w bieżącej iteracji nie znają wartości indeksu po inkrementowaniu (wykład 2, Przykł. 1). Dla tego krótkie instrukcji pętli powodują zaburzenie potoków procesora. Rozwijanie pętli w sposób sztuczny przedłuża instrukcje, co nadaje możliwość pełnego wciągnięcia potoków procesora. Przykład mnożenia macierzy przez wektor: r = r+a*v, przy czym macierz jest umieszczona w pamięci jako tablica jednowymiarowa kolumna po kolumnie: j //Brak rozwijania pętli memset((void *)R, 0, sizeof(double)*dim); for(j=0,ij=0; j<dim; j++) for(i=0; i<dim; i++, ij++) R[i] += A[ij]*V[j]; i j = A v r 0 3 6 1 4 7 2 5 8 14243 A i 0 0 1 1 2 2 v r 3

A teraz rozwiniemy pętle 6 razy: //Dostęp do elementów tablicy przez //indeksy int rest = dim%6; for(j=0, ij=0; j<dim; j++) for(i=0; i<rest; i++, ij++) R[i] += A[ij]*V[j]; for(i=rest; i<dim; i+=6, ij+=6) R[i] += A[ij] * V[j]; R[i+1] += A[ij+1]*V[j]; R[i+2] += A[ij+2]*V[j]; R[i+3] += A[ij+3]*V[j]; R[i+4] += A[ij+4]*V[j]; R[i+5] += A[ij+5]*V[j]; //Arytmetyka wskaźników double *ptr_a, *ptr_r = &A[0], *ptr_v = &V[0]; int rest = dim%6; for(j=0; j<dim; j++, ptr_v++) ptr_r = &R[0]; for(i=0; i<rest; i++, ptr_a++, ptr_r++) *ptr_r += (*ptr_v)*(*ptr_a); for(i=rest; i<dim; i+=6, ptr_a+=6, ptr_r+=6) *ptr_r += (*ptr_v)*(*ptr_a); *(ptr_r+1) += (*ptr_v)*(*(ptr_a+1)); *(ptr_r+2) += (*ptr_v)*(*(ptr_a+2)); *(ptr_r+3) += (*ptr_v)*(*(ptr_a+3)); *(ptr_r+4) += (*ptr_v)*(*(ptr_a+4)); *(ptr_r+5) += (*ptr_v)*(*(ptr_a+5)); 4

Opcje kompilatora Kompilator Visual Studio 2005 C++ (Visual Studio 8.0), jak i jego poprzedniki (Visual Studio 6.0,.) tworzy dwie wersji debug i release. Wersja debug jest przeznaczona do debagowania programu, przecież kod wysokiej wydajności można osiągnąć tylko w wersji release. 5

6

7

Opcje /O1 (minimalizacja rozmiaru kodu), /O2 (maksymalna szybkość). Włączenie tej flagi powoduje ustawienie szeregu opcji. Na przykład, włączenie /O2 powoduje ustawienie opcji: /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy /Og optymizacja globalna. Kod do optymalizacji a = b + c; d = b + c; e = b + c; Kod po optymalizacji tmp= b + c; a = d = e = tmp; o Optymalizacja lokalna są przeszukiwane tylko sąsiednie linie kodu, globalna w obszarze całej funkcji. o Kluczowe słowo register jest ignorowane. Zamiast tego kompilator umieszcza w rejestry zmienne, które mają częste powtarzania. o Usunięcie wyrażeń, które nie zależą od indeksu iteracji, poza pętle: i= -100; i = -100; while(i) tmp = x+y; i += x+y; while(i) i += tmp; 8

o Optymalizuje działanie konstruktora kopiującego i destruktora przy zwracani funkcją wartości. /Oi funkcje wbudowane (fabs(), labs(), strlen(), ) są wywołane jako intrinsic narzuty przy wywołani są usunięte. /Ot maksymalizacje szybkości wykonania *.exe, *.dll /Oy przyspiesza działania na steku przy wywołani funkcji, zwalnia jeden lub więcej rejestrów dla umieszczenia często powtarzalnych zmiennych (tylko dla x86). /Ob2 rozwinięcie inline funkcji.. 9

Superskalarność procesora możliwość wykonywania wektoryzacji elementów obliczeń przy technologii potokowej i istnieniu rejestrów specjalnych. Przykad: f = a+b+c+d; 0 2 4 6 Cykle procesora IF IF ID OF ID OF IF ID OF E IF ID OF E IF ID E IF ID WB load R1 <- a load R2 <- c R1 <- R1+b R2 <- R2+d R1 <-R1 +R2 F <- R1 (store) IF instruction fetching ID decoding OF operand fetching E execution WB Write-back 10

Floating point model: o Domyślnie (bez flagi /fp:presize) kompilator tworzy kod, który dobiera kolejność obliczeń tak, żeby przyspieszyć wykonanie kodu. Przy tym w arytmetyce zmiennoprzyczynkowej może się okazać, że kolejność operacji istotnie wpływa na wynik. o Przykład: S = S1+S2+S3+S4+. Przy sumowaniu dwóch liczb zmiennoprzyczynkowych wyrównanie jest wykonane po wartości bezwzględnej większej liczby: 1000 + 0.01 = 1.0x10 3 +0.00001x10 3. Jeśli nasz komputer nie utrymuje wystarczający rozmiar mantysy, a różnica rzędu tych liczb jest dużą, mniejsza liczba po prostu się gubi. A teraz przedstawimy, że nasz szereg zbiega się wolno, S k+1 < S k (k=1,2,,), a kompilator tworzy kod: S = S1; S = S+S2;.. Zaczynając od jakiegoś indeksu k suma S >> S k+1, i ogonek szeregu będzie pominięty. o Teraz będziemy liczyć tak: S = S N S = S+S N-1 Ogonek szeregu będzie uwzględniony 11

Ten przykład demonstruje, że bywają zagadnienia, w których wynik istotnie zależy od kolejności operacji, więc zmiana porządku operacji przy optymalizacji kodu może być dość niebezpieczną. Wyjściem z takiej sytuacji może być przedstawienie wyniku pośredniego z większą precyzją. Jeśli typ składowych float, to wynik poprzedni może być double, jeśli double long double, i t. p. o /fp:precise na procesorach x86 oznacza, że kompilator będzie wykonywał tylko bezpieczną optymalizacje na kodzie floating-point, obliczenia pośrednie (intermediate) będą wykonane z największą praktyczną dokładnością. Program, skompilowany z opcją /fp:presize, będzie wolniej i większy od programu, skompilowanego bez tej opcji. Będzie pominięta opcja /Oi (intrinsic functions), zamiast tego standardowa biblioteka runtime routines będzie użyta. o /fp:fast tworzy najszybszy kod w większości wypadków. Przecież może to powodować nieoczekiwane wyniki. o /fp:strict najbardziej ścisły model operacji zmienno przyczynkowych. Uwzględnia wszystkie korekcje /fp:presize plus do tego poprzedza nieprawidłowe przetwarzania. 12

/GL nadaje możliwość link-time code generation. Jeśli w opcjach linkera jest ustawione (a są ustawienia domyślne dla wersji release), linker i kompilator wspólnie optymalizują kod. To jest tak zwana technika profile-guided optimization (PGO). Przy zwykłej kompilacji kompilator kompiluje jednostki kompilacji rozdzielnie, i nic nie wie o związku pomiędzy tymi jednostkami. W technice PGO na podstawie wspólnej analizy (kompilator-linker) struktury programu (związku pomiędzy funkcjami i innymi jednostkami kompilacji) jest tworzony kod z optymalizowanym wywołaniem funkcji, a do tego jeszcze wielu rzeczy. Dla użycia PGO są konieczne etapy: o Kompilacje w trybie instrumentation code (opcje Linker/Optimization/Link Time Code Generation/ LTCG:PGINSTRUMENT) o Jednokrotne wykonanie programy ze zbiorem informacji w osobny plik o Przestawienie opcji linkera /LTCG:PGOPTIMIZE i ponowny rebuild programu. Optymalizacje jest wykonana automatycznie na podstawie informacji przy testowym wykonaniu programu. 13

14

Przykład: SPEC performance improvement with PGO over that of Link Time Code Generation, for all three platforms 15

16

Fiksuje typ procesora. Jest ustawiony automatycznie na danym komputerze. Kod będzie wygenerowany pod dany typ procesora. 17