Profiler
Profiler gprof
Perf
Poniższe komendy pozwalają dla danego polecenia (command) zebrać i wyświetlić statystyki liczników procesora tj. źle przewidziane skoki, nietrafienia w bufor. Narzędzie perf wymaga uprawnień roota.
# CPU counter statistics for the specified command:
perf stat command
# Detailed CPU counter statistics (includes extras) for the specified command:
perf stat -d command
# CPU counter statistics for the specified PID, until Ctrl-C:
perf stat -p PID
Zadanie 1
Przy pomocy profilera gprof przeanalizuj aplikację napisaną w C++ (to może być stary projekt zaliczeniowy, projekt open source-owy). Aplikacja ta powinna być odpowiedniego rozmiaru (więcej niż jedno plikowa ale też nie za duża).
Znajdź wąskie gardła i zaproponuj optymalizacje.
Następnie porównaj statystyki przed i po optymalizacji.
Zadanie 2
Użyj narzędzia perf
aby zbadać z czego wynikają różnice w działaniu wersji 1 i 2 poniższego programu cache.cpp
.
/**
* @file cache2.cpp
* Kompilacja:
* g++ cache.cpp -O2 -o cache -std=c++11
*/
#include <iostream>
#include <chrono>
#include <ctime>
using namespace std;
int main() {
const int M = 256; // Sprawdź też rozmiary 128, 512, 1024
int i, j, k;
int tab[M][M];
chrono::time_point<chrono::system_clock> start, end;
start = chrono::system_clock::now();
for(k=0; k<1000; k++){
for(i=0; i<M; i++){
for(j=0; j<M; j++){
tab[j][i] = j*i+k; // Wersja 1.
//~ tab[i][j] = j*i+k; // Wersja 2.
}
}
}
end = chrono::system_clock::now();
chrono::duration<double> elapsed_seconds = end-start;
cout << "elapsed time: " << elapsed_seconds.count() << "s\n";
int suma=0;
for(int i=0; i<M; i++){
for(int j=0; j<M; j++){
suma+= tab[i][j];
}
}
cout << suma <<endl; }
Zadanie 3.
Poniższy pogram liczy sumę elementów w tablicy tab, które są mniejsze niż dany próg THRESHOLD.
Użyj narzędzia perf aby zbadać z czego wynikają różnice w działaniu poniższego programu dla tablicy posortowanej i losowej.
/// @file cache2.cpp
/// Kompilacja:
/// g++ cache2.cpp -O2 -o cache2 -std=c++11
#include <iostream>
#include <chrono>
#include <ctime>
#include <climits>
#include <algorithm>
using namespace std;
int main() {
const int M = 256*256; // array size
const int ITER = 10000; // number of iterations
const int THRESHOLD = 128;
int i, k;
unsigned char tab[M];
std::srand(0);
std::generate(tab, tab+M, []{return std::rand()%256;});
//~ std::sort(tab, tab+M); ///<<<<<<<<<<<<<<<<<<< SORT
std::chrono::time_point<std::chrono::system_clock> start, end;
start = std::chrono::system_clock::now();
int sum=0;
for(k=0; k<ITER; k++){
for(i=0; i<M; i++){
if(tab[i] < THRESHOLD ){
sum += tab[i];
}
}
}
end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = end-start;
std::cout << "\nelapsed time: " << elapsed_seconds.count() << "s\n";
std::cout << sum<<std::endl;
}