Help mesure des performances de la parallelis
Bonjour,
je suis étudiante en 3eme informatique et j'ai comme thème mesure des performances de la parallélisation en mémoire partagée je travail donc sur le produit de deux matrices avec la bibliothèque open mp sous linux enfin ubunto mais j'avoue etre vraiment perdue pour le programme
j'ai besoin d'aide alors si quelqu'un peut m'aider !!!!!!!!!!
je suis étudiante en 3eme informatique et j'ai comme thème mesure des performances de la parallélisation en mémoire partagée je travail donc sur le produit de deux matrices avec la bibliothèque open mp sous linux enfin ubunto mais j'avoue etre vraiment perdue pour le programme
j'ai besoin d'aide alors si quelqu'un peut m'aider !!!!!!!!!!
A voir également:
- Help mesure des performances de la parallelis
- Diagnostic de performance énergétique - Accueil - Maison
- Tester les performances de son pc - Guide
- Mesure avec telephone - Guide
- Comment voir les performances de son pc - Guide
- Optimiseur de performance pc gratuit - Accueil - Utilitaires
1 réponse
Je pense que le point de départ c'est cherché un tutoriel basique, tenter de le reproduire, et ensuite de le corriger petit à petit pour atteindre ton objectif. Tu peux par exemple partir de ceci :
https://www.azote.org/disabled.html
Dans le cas d'un produit matriciel A * B = C, le calcul de chaque terme de C est indépendant, donc on peut calculer en parallèle tous les coefficients de C :
https://www.azote.org/disabled.html
Il faut donc commencer par définir une classe dans lesquelles stocker tes matrices. Par exemple si tu codes en C++ tu peux par exemple écrire un truc du genre :
Voici à quoi ressemblerait par exemple le code d'une matrice générique en C++ (ici je n'ai codé que ce qui permet de créer la matrice, d'accéder à ses éléments a[i][j] (opérateurs []), de calculer le produit de deux matrices (opérateur *), et de l'afficher (opérateur <<).
matrix.hpp
main.cpp
Ensuite on compile :
... et on exécute :
Ce qui donne :
Ok c'est cool maintenant, revenons à openmp. Dans notre cas c'est la multiplication qui nous préoccupe. Tu noteras que << ne serait pas parallélisable car chaque coefficient de la matrice doit être écrit "dans l'ordre" (de haut en bas et de gauche à droite). Dans le cas du produit matriciel, peut importe l'ordre dans lequel les coefficients de C sont calculés. On s'intéresse donc à cette partie du code :
Comme tu le vois ici les trois boucles imbriquées induisent un calcul successif de chaque terme (ce qui signifie qu'on va d'abord calculer c[0][0], puis c[0][1], puis etc... ce qui est dommage car leur calcul est indépendant. C'est là qu'openmp va nous sortir d'affaire. Je n'ai jamais utilisé cette librairie, mais toujours d'après ce lien :
https://www.azote.org/disabled.html
... il suffirait de rajouter #pragma omp parallel for devant chaque boucle for. En enlevant rajoutant ce #pragma, tu verras bien si tu le calcul est correct, mais dans l'idée je pense que le code deviendrait un truc du genre :
Bonne chance
https://www.azote.org/disabled.html
Dans le cas d'un produit matriciel A * B = C, le calcul de chaque terme de C est indépendant, donc on peut calculer en parallèle tous les coefficients de C :
https://www.azote.org/disabled.html
Il faut donc commencer par définir une classe dans lesquelles stocker tes matrices. Par exemple si tu codes en C++ tu peux par exemple écrire un truc du genre :
Voici à quoi ressemblerait par exemple le code d'une matrice générique en C++ (ici je n'ai codé que ce qui permet de créer la matrice, d'accéder à ses éléments a[i][j] (opérateurs []), de calculer le produit de deux matrices (opérateur *), et de l'afficher (opérateur <<).
matrix.hpp
#ifndef MATRIX_HPP
#define MATRIX_HPP
#include <vector>
#include <ostream>
template <typename T>
class matrix_t {
private:
std::size_t n_rows;
std::size_t n_cols;
std::vector<std::vector<T> > values;
public:
matrix_t(){}
matrix_t(
std::size_t n_rows0,
std::size_t n_cols0
):
n_rows(n_rows0),
n_cols(n_cols0)
{
this->values = std::vector<std::vector<T> >(
n_rows,
std::vector<T>(n_cols)
);
}
inline std::size_t num_rows() const {
return this->n_rows;
}
inline std::size_t num_cols() const {
return this->n_cols;
}
// Accès à une ligne (lecture)
inline const std::vector<T> & operator[](std::size_t & row) const {
return this->values[row];
}
// Accès à une ligne écriture (lecture)
inline std::vector<T> & operator[](std::size_t & row){
return this->values[row];
}
};
// Multiplication
template <typename T>
matrix_t<T> operator * (
const matrix_t<T> & a,
const matrix_t<T> & b
) {
if(a.num_cols() != b.num_rows()) throw;
matrix_t<T> c = matrix_t<T>(
a.num_rows(),
b.num_cols()
);
for(std::size_t i = 0; i < a.num_rows(); i++) {
for(std::size_t j = 0; j < a.num_cols(); j++) {
for(std::size_t k = 0; k < b.num_cols(); k++) {
c[i][k] = a[i][j] * b[j][k];
}
}
}
return c;
}
// Affichage
template <typename T>
std::ostream & operator << (
std::ostream & out,
const matrix_t<T> matrix
) {
for(std::size_t i = 0; i < matrix.num_rows(); i++) {
for(std::size_t j = 0; j < matrix.num_cols(); j++) {
out << matrix[i][j] << '\t';
}
out << std::endl;
}
return out;
}
#endif
main.cpp
#include <iostream>
#include "matrix.hpp"
int main(){
matrix_t<int> a(5, 3);
matrix_t<int> b(3, 4);
for(std::size_t i = 0; i < a.num_rows(); i++) {
for(std::size_t j = 0; j < a.num_cols(); j++) {
a[i][j] = i + 10*j;
}
}
for(std::size_t i = 0; i < b.num_rows(); i++) {
for(std::size_t j = 0; j < b.num_cols(); j++) {
b[i][j] = 10*i + 100*j;
}
}
matrix_t<int> c = a * b;
std::cout << "a = " << std::endl << a << std::endl
<< "b = " << std::endl << b << std::endl
<< "c = " << std::endl << c << std::endl;
return 0;
}
Ensuite on compile :
g++ -W -Wall main.cpp -o matrice
... et on exécute :
./matrice
Ce qui donne :
a = 0 10 20 1 11 21 2 12 22 3 13 23 4 14 24 b = 0 100 200 300 10 110 210 310 20 120 220 320 c = 400 2400 4400 6400 420 2520 4620 6720 440 2640 4840 7040 460 2760 5060 7360 480 2880 5280 7680
Ok c'est cool maintenant, revenons à openmp. Dans notre cas c'est la multiplication qui nous préoccupe. Tu noteras que << ne serait pas parallélisable car chaque coefficient de la matrice doit être écrit "dans l'ordre" (de haut en bas et de gauche à droite). Dans le cas du produit matriciel, peut importe l'ordre dans lequel les coefficients de C sont calculés. On s'intéresse donc à cette partie du code :
...
for(std::size_t i = 0; i < a.num_rows(); i++) {
for(std::size_t j = 0; j < a.num_cols(); j++) {
for(std::size_t k = 0; k < b.num_cols(); k++) {
c[i][k] = a[i][j] * b[j][k];
}
}
}
...
Comme tu le vois ici les trois boucles imbriquées induisent un calcul successif de chaque terme (ce qui signifie qu'on va d'abord calculer c[0][0], puis c[0][1], puis etc... ce qui est dommage car leur calcul est indépendant. C'est là qu'openmp va nous sortir d'affaire. Je n'ai jamais utilisé cette librairie, mais toujours d'après ce lien :
https://www.azote.org/disabled.html
... il suffirait de rajouter #pragma omp parallel for devant chaque boucle for. En enlevant rajoutant ce #pragma, tu verras bien si tu le calcul est correct, mais dans l'idée je pense que le code deviendrait un truc du genre :
...
#pragma omp parallel
for(std::size_t i = 0; i < a.num_rows(); i++) {
#pragma omp parallel
for(std::size_t j = 0; j < a.num_cols(); j++) {
#pragma omp parallel
for(std::size_t k = 0; k < b.num_cols(); k++) {
c[i][k] = a[i][j] * b[j][k];
}
}
}
...
Bonne chance