-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmatrixPalFork.c
158 lines (123 loc) · 3.87 KB
/
matrixPalFork.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
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define MAX_PROCESSES 10 //number of processes
// struct to save the processes's args
typedef struct {
int id; // process ID
int **a; // Matrix A
int **b; // Matrix B
int **result; // result Matrix
int n; // matrix size
int num_processes; // total number of process
} ProcessArgs;
//random number generation
int randomNumber(){
int upper = 100, lower = 1;
int num = (rand() % (upper - lower + 1)) + lower;
return num;
}
void fillMatrix(int **matrixPointer, int *n){
int i, j;
for (i = 0; i < *n; i++) {
for (j = 0; j < *n; j++) {
matrixPointer[i][j] = randomNumber();
}
}
}
void printMatrix(int **matrixPointer, int *n){
int i, j;
for (i = 0; i < *n; i++) {
for (j = 0; j < *n; j++) {
printf("%d\t", matrixPointer[i][j]);
}
printf("\n");
}
}
// Function to multiply a portion of the matrixes
void multiplyMatrixSegment(ProcessArgs *processArgs) {
int id = processArgs->id;
int n = processArgs->n;
int num_processes = processArgs->num_processes;
int start_row = id * (n / num_processes);
int end_row = (id == num_processes - 1) ? n : (id + 1) * (n / num_processes);
clock_t t;
t = clock();
for (int i = start_row; i < end_row; i++) {
for (int j = 0; j < n; j++) {
processArgs->result[i][j] = 0;
for (int k = 0; k < n; k++) {
processArgs->result[i][j] += processArgs->a[i][k] * processArgs->b[k][j];
}
}
}
t = clock() - t;
double time_taken = ((double)t) / CLOCKS_PER_SEC; // Tiempo en segundos
printf("[%d] Hilo %d: El tiempo de ejecucion fue de %f segundos\n",n, id, time_taken);
}
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
int verbose = 0;
if (argc == 3 && strcmp(argv[2], "verbose") == 0) {
verbose = 1;
}
// Create matrixes a, b & result
int **a = (int **)malloc(n * sizeof(int *));
int **b = (int **)malloc(n * sizeof(int *));
int **axb = (int **)malloc(n * sizeof(int *));
for (int i = 0; i < n; i++) {
a[i] = (int *)malloc(n * sizeof(int));
b[i] = (int *)malloc(n * sizeof(int));
axb[i] = (int *)malloc(n * sizeof(int));
}
//filling the matrix
fillMatrix(a, &n);
fillMatrix(b, &n);
// Create processes
pid_t child_pids[MAX_PROCESSES];
ProcessArgs processArgs[MAX_PROCESSES];
for (int i = 0; i < MAX_PROCESSES; i++) {
// Create processes son
pid_t child_pid = fork();
if (child_pid == 0) {
// process son
processArgs[i].id = i;
processArgs[i].a = a;
processArgs[i].b = b;
processArgs[i].result = axb;
processArgs[i].n = n;
processArgs[i].num_processes = MAX_PROCESSES;
multiplyMatrixSegment(&processArgs[i]);
exit(0); // Exit the child process after completing its work
} else if (child_pid > 0) {
// Process father: to save the PID of process son
child_pids[i] = child_pid;
} else {
// Error to create process son
fprintf(stderr, "Error al crear el proceso hijo.\n");
return 1;
}
}
// Wait for child processes to finish
for (int i = 0; i < MAX_PROCESSES; i++) {
waitpid(child_pids[i], NULL, 0);
}
//matrix print if verbose parameter is present
if(verbose){
printf("The matrix a is: \n");
printMatrix(a, &n);
printf("The matrix b is: \n");
printMatrix(b, &n);
printf("The product of the two matrices is: \n");
printMatrix(axb, &n);
}
//free memory
free(a);
free(b);
free(axb);
return 0;
}