]> vgcfreebox.myrthtech.pt Git - ue-pp-squarematrixparallelisation.git/blob - ParallelMatrixSearch.c
little help from gemini :)
[ue-pp-squarematrixparallelisation.git] / ParallelMatrixSearch.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <pthread.h>
4 #include <time.h>
5
6 const int m_rows = 40000;
7 const int m_cols = m_rows;
8
9 _Atomic int hv = 0;
10 int **matrix;
11
12 typedef struct{
13 int start;
14 int end;
15 } thread_args;
16
17 void* parallel_search_cols(void *arg){
18 thread_args *args = (thread_args *)arg;
19 for(int r = 0; r < m_rows; r++){
20 for(int c = args->start; c < args->end; c++){
21 if(matrix[r][c] > hv){
22 hv = matrix[r][c];
23 }
24 }
25 }
26 free(args);
27 return NULL;
28 }
29
30 // Function to dynamically create threads and divide columns
31 void run_parallel_search(int num_threads) {
32 // 1. Dynamically allocate arrays for threads and their arguments
33 pthread_t *threads = malloc(num_threads * sizeof(pthread_t));
34 thread_args *args = malloc(num_threads * sizeof(thread_args));
35
36 if (threads == NULL || args == NULL) {
37 perror("Failed to allocate memory for threads");
38 exit(1);
39 }
40
41 // 2. Calculate the base number of columns each thread will process
42 int chunk_size = m_cols / num_threads;
43
44 // 3. Create the threads in a loop
45 for (int i = 0; i < num_threads; i++) {
46 args[i].start = i * chunk_size;
47
48 // If it is the last thread, let it process all remaining columns
49 if (i == num_threads - 1) {
50 args[i].end = m_cols;
51 } else {
52 args[i].end = (i + 1) * chunk_size;
53 }
54
55 // Pass the address of the specific struct for this thread
56 if (pthread_create(&threads[i], NULL, &parallel_search_cols, &args[i]) != 0) {
57 perror("Failed to create thread");
58 exit(1);
59 }
60 }
61
62 // 4. Wait for all threads to finish
63 for (int i = 0; i < num_threads; i++) {
64 pthread_join(threads[i], NULL);
65 }
66
67 // 5. Clean up the dynamically allocated arrays
68 free(threads);
69 // Note: Do not free(args) here IF your thread function (parallel_search_cols)
70 // is already calling free(arg) internally!
71 // Since your original thread function calls free(args), calling it here
72 // would cause a "double free" crash.
73 // However, since we allocated it as one big array, it is better to remove
74 // free(args) from your thread function and do it here:
75 free(args);
76 }
77
78 int main(void){
79 printf("1st --> Allocate memory\n");
80 clock_t t_t1; t_t1 = clock();
81 size_t rows_size = m_rows * sizeof(int*);
82 matrix = malloc(rows_size);
83 if(matrix == NULL){
84 perror("malloc failled");
85 return 1;
86 }
87 size_t data_size = (size_t)m_rows * m_cols * sizeof(int);
88 int *data;
89 if(posix_memalign((void**)&data, 64, data_size) != 0){
90 perror("not able to alocate memory");
91 free(matrix);
92 return 1;
93 }
94 t_t1 = clock() - t_t1;
95 double t1_ttaken = ((double)t_t1)/CLOCKS_PER_SEC;
96 printf(" %f sec\n",t1_ttaken);
97
98 printf("2nd --> Populate the matrix\n");
99 clock_t t_t2; t_t2 = clock();
100 for(int r = 0; r<m_rows;r++){
101 matrix[r] = data + r * m_cols;
102 }
103 for(int r = 0; r < m_rows; r++){
104 for(int c = 0; c < m_cols; c++){
105 matrix[r][c] = r*m_cols+c;
106 }
107 }
108 t_t2 = clock() - t_t2;
109 double t2_ttaken = ((double)t_t2)/CLOCKS_PER_SEC;
110 printf(" %f sec\n",t2_ttaken);
111
112 printf("3rd --> Search matrix\n");
113 clock_t t_t3; t_t3 = clock();
114 int threads_to_use = 4;
115 run_parallel_search(threads_to_use);
116 t_t3 = clock() - t_t3;
117 double t3_ttaken = ((double)t_t3)/CLOCKS_PER_SEC;
118 printf(" %f sec\n",t3_ttaken);
119
120 printf("Done\n The biggest value found is %d", hv);
121 free(data);
122 free(matrix);
123 return 0;
124 }