-
Notifications
You must be signed in to change notification settings - Fork 0
/
divideMat.c
219 lines (187 loc) · 6.25 KB
/
divideMat.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/*
* UNICAMP - Universidade Estadual de Campinas
* FT - Faculdade de Tecnologia
* Limeira - SP
*
* GRUPO - KGBcomM
*
* Matheus Percario Bruder RA: 222327
* Kevin Barrios RA: 219643
* Gustavo Tarrafil RA: 159740
*
* Maio/2019
*/
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
/* ----------------------------------------------------------------- */
/* Estrutura da informcoes necessaria para referenciar a thread ---- */
typedef struct informacoes
{
int ID;
int Dimensao;
int num_Threads;
int Posicao;
double ** matriz;
double ** diag1;
double ** diag2;
} INFORMACOES;
/* ----------------------------------------------------------------- */
/* Variaveis globais: ---------------------------------------------- */
// Pode ser criados até 16 threads
pthread_t vThread[16];
// 16 Struct de cada thread
INFORMACOES info[16];
/* ----------------------------------------------------------------- */
/* Funcoes globais: retornar linha e coluna ------------------------ */
int linha (int Dimens, int Posic)
{
int ID_Linha = Posic/Dimens;
return ID_Linha;
}
int coluna (int Dimens, int Posic)
{
int ID_Coluna = Posic % Dimens;
return ID_Coluna;
}
/* ----------------------------------------------------------------- */
/* Funcao DividirMatriz da thread ---------------------------------- */
/* ----------------------------------------------------------------- */
void * threadDividirMatriz(void * Argumentos){
INFORMACOES * info = Argumentos;
while (info->Posicao < (info->Dimensao * info->Dimensao)){
int LIN = linha(info->Dimensao, info->Posicao);
int COL = coluna(info->Dimensao, info->Posicao);
double Posicao = info->matriz[LIN][COL];
if (COL >= LIN) { info->diag2[LIN][COL] = info->matriz[LIN][COL]; info->diag1[LIN][COL] = 0.0; }
else { info->diag1[LIN][COL] = info->matriz[LIN][COL]; info->diag2[LIN][COL] = 0.0; }
//printf("Posicao Atual thread[%d]: %d\n", info->ID, info->Posicao);
info->Posicao = info->num_Threads + info->Posicao;
//printf("Proxima pos. thread[%d]: %d\n", info->ID, info->Posicao);
}
}
/* ----------------------------------------------------------------- */
/* Funcao Principal ------------------------------------------------ */
/* ----------------------------------------------------------------- */
int main (int argc, char * argv[])
{
int i, j, N, T;
N = atoi(argv[1]);
T = atoi(argv[2]);
clock_t tempoInicial;
clock_t tempoFinal;
double tempoExecucao;
printf("Dimensão da matriz: %d\n", N);
printf("Numero de threads: %d\n", T);
printf("Arquivo: %s\n\n", argv[3]);
if(T==2 || T==4 || T==8 || T==16)
{
/* ----------------------------------------------------------------- */
/* Alocar TODAS matrizes dinamicamente ----------------------------- */
//OBS.: matrizes foram alocadas dinamicamente para facilitar
//a passagem por parametro dentro da struct (alem de evitar
//estouro de pilha)!
// Malloc - matriz principal
double **matriz_p;
matriz_p = (double **) malloc (N * sizeof(double *));
for (i = 0; i < N; i++)
{
matriz_p[i] = (double *) malloc (N * sizeof(double));
}
// Malloc - matriz diag1
double **diag1;
diag1 = (double **) malloc (N * sizeof(double *));
for (i = 0; i < N; i++)
{
diag1[i] = (double *) malloc (N * sizeof(double));
}
// Malloc - matriz diag2
double **diag2;
diag2 = (double **) malloc (N * sizeof(double *));
for (i = 0; i < N; i++)
{
diag2[i] = (double *) malloc (N * sizeof(double));
}
/* ----------------------------------------------------------------- */
/* Escanear Matriz.txt gerada aleatoriamente! ---------------------- */
FILE * arq;
arq = fopen(argv[3], "r");
if (arq == NULL) { printf("ERRO ao abrir o arquivo!\n\n"); }
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
fscanf(arq, "%lf", &matriz_p[i][j]);
}
}
fclose(arq);
/* ----------------------------------------------------------------- */
/* Criacao das threads! -------------------------------------------- */
//Sinalização do começo
tempoInicial = clock();
// Criar numero de threads necessarias e passar
//informacoes para funcao threads
for (i = 0; i < T; i++)
{
//info struct criada em cima
info[i].ID = i;
info[i].Dimensao = N;
info[i].num_Threads = T;
info[i].Posicao = i;
info[i].matriz = matriz_p;
info[i].diag1 = diag1;
info[i].diag2 = diag2;
// Criando a thread e passando referencias
//referencias:
// &vThread[i]: Qual é a thread dentre o vetor de threads
// threadDividirMatriz: Funcao da thread
// (void *)&info[i]: Endereco da struct referente a thread
pthread_create(&vThread[i], NULL, threadDividirMatriz, (void *)&info[i]);
}
for (i = 0; i < T; i++)
{
// "pthread_join" faz que a main espere que
//todas threads acabarem
pthread_join(vThread[i], NULL);
}
//Sinalizacao do final
tempoFinal = clock();
//Tempo total de execucao
tempoExecucao = (tempoFinal - tempoInicial) * 1000.0 / CLOCKS_PER_SEC;
printf("\nTempo de execucao: %.3lf ms\n", tempoExecucao);
/* ----------------------------------------------------------------- */
/* Printar matriz diag2 no arquivo txt! ---------------------------- */
arq = fopen("Matriz.diag2", "w");
if (arq == NULL) { printf("ERRO ao abrir o arquivo!\n"); }
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
fprintf(arq, "%lf\t", diag1[i][j]);
}
fprintf(arq, "\n");
}
fclose(arq);
/* ----------------------------------------------------------------- */
/* Printar matriz diag1 no arquivo txt! ---------------------------- */
arq = fopen("Matriz.diag1", "w");
if (arq == NULL) { printf("ERRO ao abrir o arquivo!\n"); }
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
fprintf(arq, "%lf\t", diag2[i][j]);
}
fprintf(arq, "\n");
}
fclose(arq);
}
/* ----------------------------------------------------------------- */
/* Numero de threads invalido! ------------------------------------ */
else
{
printf("Numero de threads invalido!\n\n");
return 1;
}
return 0;
}