C - prodotto matrici con openmp

di il
4 risposte

C - prodotto matrici con openmp

Salve a tutti
spero che qualcuno possa aiutarmi, ho scritto un algoritmo per il calcolo del prodotto matrice x matrice in ambiente openmp, il metodo utilizzato è quello della suddivisione della matrice A in blocchi di colonne e della matrice b in blocchi di righe(assegnando ai vari processori i blocchi delle 2 matrici).
il programma funziona ma ho notato che la differenza di perfomance tra 4 e 8 processori è minima.
qualcuno sa dirmi dove sbaglio????


di seguito il codice:
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>

int ** creamat(int);
void riempimat(int **, int);
double prodottopar(int **, int **, int **, int, int);
void stampamat(int **, int);
void libera(int **, int);


void main(int argc, char **argv)
{
	int n,p;
	int **a,**b,**c, **cseq;
    double i_timetot, f_timetot, d_timetot, f_timeseq, f_timepar, d_timeseqpar;   //usate per il calcolo con omp_get_wtime();
    
    i_timetot=omp_get_wtime();
	printf("Inserisci il numero di processori MAX 8: ");
    scanf("%d",&p);

    printf("inserisci la dimensione di n: ");
    scanf("%d",&n);

	a=creamat(n);
	b=creamat(n);
	c=creamat(n);
	
	riempimat(a,n);
	riempimat(b,n);

    f_timepar=prodottopar(a,b,c,p,n);
    
    /*printf("Matrice con calcolo sequenziale\n\n");
	stampamat(cseq,n);*/
    
    /*printf("Matrice con calcolo Parallelo\n\n");
	stampamat(c,n);*/
    
    f_timetot=omp_get_wtime();
    d_timetot=f_timetot - i_timetot;
	printf("Report Tempi Prodotto Mat x Mat con n= %d ed uso di %d Processori:\n\n",n,p);
    printf("Tempo Calcolo parallelo: %f sec.\n\nTempo Totale di esecuzione algoritmo: %f sec.\n\n", f_timepar, d_timetot);
	libera(a,n);
	libera(b,n);
	libera(c,n);
}



//INIZIO FUNZIONI

//creazione dinamica delle matrici
int ** creamat(int num)
{
	int i;
	int **mat;
	mat=(int **)calloc(num,sizeof(int*));
    for(i=0;i<num;i++)
    {
        mat[i]=(int *)calloc(num,sizeof(int));
    }
	return mat;
}

void riempimat(int **mat, int num)
{
	int i,j;
	for(i=0;i<num;i++)
	{
		for(j=0;j<num;j++)
		{
			mat[i][j]=1;
		}
	}
}


double prodottopar(int **ma, int **mb, int ** mc, int proc, int num)
{
	int i,j,k;
	int **mat;
    double tempoinizio, tempofine;

    
    tempoinizio=omp_get_wtime();

	#pragma omp parallel num_threads(proc) default(none) private(i,j,k,mat) shared(ma,mb,mc,num,proc)
    {
		mat=creamat(num);
		for(i=0;i<num;i++)
			{
				for(j=0;j<num;j++)
				{
					#pragma omp for schedule(static)
					for(k=0;k<num;k++){
						mat[i][j]+=ma[i][k]*mb[k][j];
					}
				}
			}

		//scrittura nella matrice c
		#pragma omp critical
        for(i=0;i<num;i++)
        {
            for(j=0;j<num;j++)
            {
                mc[i][j]+=mat[i][j];
            }
        }
	}
    //libera(mat,num);
    tempofine=omp_get_wtime()-tempoinizio;
	return tempofine;
    
}

void stampamat(int **mat, int num)
{
	int i,j;
	for(i=0;i<num;i++)
	{
		for(j=0;j<num;j++)
		{
			printf("%d ",mat[i][j]);
		}
		printf("\n");
	}
}

void libera(int **mat, int num)
{
	int i;
	for(i=0;i<num;i++)
	{
		free(mat[i]);
	}
	free(mat);
}

4 Risposte

  • Re: C - prodotto matrici con openmp

    1) hai un PC con 8 core (in realta' 4 core + hyperthreading)?

    2) 'proc' vale 8?

    3) dove sta' il partizionamento? Tutti i thread fanno lo stesso calcolo: 'mat = ma x mb', anche se mat e' locale al thread!

    4) evita la direttiva private(...), sposta le variabili private all'interno del body del thread (dopo "{").
  • Re: C - prodotto matrici con openmp

    Ciao Migliorabile
    scusa se ho omesso dei dettagli, cmq in risposta alle tue domande:

    1 - si abbiamo a disposizione dallafacolta un 4 core + hyperthreading.

    2 - il partizionamento lo faccio con il ciclo + interno

    #pragma omp for schedule(static)
    for(k=0;k<num;k++){
    mat[j]+=ma[k]*mb[k][j];

    visto che devo fare la suddivisone in blocchi di colonne della matrice A e blocchi di righe della matrice B


    3 - proc viene decisa dall'utente ad inizio programma (ho effettuato dei test con tutti i processori, da 1 a 8, e dal 5 si ha un peggioramento dovuto all'hyperthreading che poi migliora fino all'8° che cmq ha poca differenza rispetto a 4 processori)
  • Re: C - prodotto matrici con openmp

    Non avevo visto il secondo pragma. E solo ora l'ho provato.
    Compilare con gcc sul cellulare e' un po' scomodo !

    I thread virtuali non sono efficienti come i thread fisici, ma fanno il loro sporco mestiere.

    Qui il problema e' che il for che parallelizzi e' quello troppo interno.

    Ti conviene usare i thread sempre al livello piu' alto possibile. Altrimenti rischi di peggiorare i risultati, invece di migliorarli, perche' perdi un sacco di tempo per lo startup dei thread, poi fai fare loro troppo poco lavoro, e alla fine li getti via.
    Non molto intelligente.
  • Re: C - prodotto matrici con openmp

    Il problema è che l'algoritmo deve suddividere la matrice A in blocchi di colonne e la matrice B in blocchi di righe (e moltiplicarli tra loro), x questo ho suddiviso il ciclo for più interno, devo vedere di trovare un'altra soluzione, sono accettati consigli
Devi accedere o registrarti per scrivere nel forum
4 risposte