Ciao ragazzi,
sono sempre io che tento di parallelizzare utilizzando openmp!
Sto provando a parallelizzare una semplice moltiplicazione fra 2 matrici riempite di '1'... Tutto ok nell'esecuzione del programma se non che ho un problemino con il numero dei threads all'interno della parallelizzazione. Quando chiedo ad ogni thread di dirmi il proprio numero mi viene fuori che un thread è doppio o triplo e non riesco a capire il perchè!!!!
Vi posto il codice (spero sia chiaro):
#include <stdio.h>
#include <omp.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
//Dichiarazione delle variabili, delle dimensioni
int i,j,k,nt=4,m=5,h=5,n=5; //delle matrici e del numero di threads (nt)
int num,esimo,procs;
double tempotot,start,end;
unsigned int result=0; //variabile d'appoggio
//Allocazione dinamica delle due matrici da moltiplicare e della matrice risultato C
int* A=(int*)calloc(m*h,sizeof(int*));
int* B=(int*)calloc(h*n,sizeof(int*));
int* C=(int*)calloc(m*n,sizeof(int*));
for(i=0;i<m;i++) //Riempimento della matrice A
for(j=0;j<h;j++)
A[j+i*h]=1; //Utilizzeremo una matrice costituita da tutti 1
for(i=0;i<h;i++) //Riempimento della matrice B
for(j=0;j<n;j++)
B[j+i*n]=1; //Utilizzeremo una matrice costituita da tutti 1
printf("Stampo le matrici A e B: \n");
for(i=0;i<m;i++){ //Stampa delle matrici
for(j=0;j<h;j++){
printf("%d ",A[j+i*h]);
}
printf("\n");
}
printf("\n");
for(i=0;i<h;i++){
for(j=0;j<n;j++){
printf("%d ",B[j+i*n]);
}
printf("\n");
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Controllo core e threads @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
num = omp_get_num_threads();
esimo = omp_get_thread_num();
procs = omp_get_num_procs();
printf("\nSono disponibili %d core.\n",procs);
printf("Fuori dalla zona parallela ci sono %d thread e questo è il thread num %d.\n\n",num,esimo);
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//Inizio calcolo dei tempi
start=omp_get_wtime();
//Inizio parte parallela:
#pragma omp parallel for schedule(dynamic) num_threads(nt) shared(m,n,h,A,B,C) private(j,k,result)
for(i=0;i<m;i++){
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Controllo dentro alla parte parallelizzata @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
num = omp_get_num_threads();
esimo = omp_get_thread_num();
printf("Qui (dentro al for #pragma) ci sono %d threads, io sono il numero %d\n",num,esimo);
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
for(j=0;j<n;j++){
result=0; //Resetto la variabile d'appoggio
for(k=0;k<h;k++)
result=result+A[k+i*h]*B[j+k*n];
C[j+i*n]=result; //l'uso di questa variabile permette di evitare il problema del false sharing
}
}
end=omp_get_wtime(); //Fine calcolo dei tempi
tempotot=end-start;
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Fuori dalla parallelizzazione @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
num = omp_get_num_threads();
esimo = omp_get_thread_num();
printf("\nQui (fine #pragma) ci sono %d threads, io sono il numero %d.\n",num,esimo);
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
printf("\nRisultato della moltiplicazione:\n"); //Stampa finale del risultato
for(i=0;i<m;i++){
for(j=0;j<n;j++){
printf("%d ",C[j+i*n]);
}
printf("\n");
}
printf("\nTempo totale : %f secondi.\n",tempotot);
// Esecuzione del programma in modo sequenziale
printf("\nEsegue il codice in modo sequenziale: ");
start=omp_get_wtime();
for(i=0;i<m;i++){
for(j=0;j<n;j++){
result=0;
for(k=0;k<h;k++)
result=result+A[k+i*h]*B[j+k*n];
C[j+i*n]=result;
}
}
end=omp_get_wtime();
tempotot=end-start;
printf("tempo totale : %f secondi.\n",tempotot);
free(A); //Deallocazione delle matrici
free(B);
free(C);
}
Infine vi chiedo anche se sapete spiegarmi perchè eseguendo il programma in modo sequenziale ci mette meno tempo rispetto all'esecuzione in parallelo...
Vi posto anche l'output:
[xPecax@localhost ~]$ ./a.out
Stampo le matrici A e B:
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
Sono disponibili 4 core.
Fuori dalla zona parallela ci sono 1 thread e questo è il thread num 0.
Qui (dentro al for #pragma) ci sono 4 threads, io sono il numero 3
Qui (dentro al for #pragma) ci sono 4 threads, io sono il numero 3
Qui (dentro al for #pragma) ci sono 4 threads, io sono il numero 3
Qui (dentro al for #pragma) ci sono 4 threads, io sono il numero 2
Qui (dentro al for #pragma) ci sono 4 threads, io sono il numero 1
Qui (fine #pragma) ci sono 1 threads, io sono il numero 0.
Risultato della moltiplicazione:
5 5 5 5 5
5 5 5 5 5
5 5 5 5 5
5 5 5 5 5
5 5 5 5 5
Tempo totale : 0.017916 secondi.
Esegue il codice in modo sequenziale: tempo totale : 0.000002 secondi.
[xPecax@localhost ~]$
In questo caso ho il thread numero 3 che mi esce 3 volte!!!!