Skip to content

Instantly share code, notes, and snippets.

@panta
Created April 20, 2022 10:20
Show Gist options
  • Save panta/065699943ba0e8975544e41288a9a1eb to your computer and use it in GitHub Desktop.
Save panta/065699943ba0e8975544e41288a9a1eb to your computer and use it in GitHub Desktop.
ITS Meccatronico - Soluzione esercizio 3 lezione 6
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
// Data la definizione di prodotto scalare
// tra vettori enunciata qui sopra,
// scrivere un programma single-threaded
// che calcoli il prodotto scalare tra
// due vettori di double di grande
// dimensione (es. 10k elementi).
// Scrivere una versione del programma
// multi-threaded con NUM_THREADS
// threads che divida il lavoro tra
// i vari thread. Verificare che i
// risultati siano identici alla
// versione single-threaded.
// Confrontare le performance con la
// versione single-threaded.
#define NUM_THREADS 4
double dot(double u[], double v[], int size) {
double r = 0.0;
for (int i = 0; i < size; i++)
r += u[i] * v[i];
return r;
}
void fillrand(double u[], int size) {
for (int i = 0; i < size; i++) {
u[i] = ((double)rand() / (double)RAND_MAX);
}
}
void printvec(double u[], int size) {
printf("[");
for (int i = 0; i < size; i++) {
printf("%g", u[i]);
if (i + 1 < size)
printf(", ");
}
printf("]\n");
}
struct subvecs {
double *u;
double *v;
double r;
int size;
};
void *threadfunc(void *param) {
struct subvecs *work = (struct subvecs *)param;
work->r = dot(work->u, work->v, work->size);
return NULL;
}
double mt_dot(double u[], double v[], int size) {
int size_per_thread = size / NUM_THREADS;
pthread_t tid[NUM_THREADS];
struct subvecs work[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
work[i].u = &u[i * size_per_thread];
work[i].v = &v[i * size_per_thread];
work[i].size = size_per_thread;
if (pthread_create(&tid[i], NULL, threadfunc, &work[i]) != 0) {
perror("pthread_create");
exit(EXIT_FAILURE);
}
}
double r = 0.0;
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(tid[i], NULL);
r += work[i].r;
}
return r;
}
#define BIGVECSIZE 800000
double g_u[BIGVECSIZE];
double g_v[BIGVECSIZE];
int main() {
fillrand(g_u, BIGVECSIZE);
fillrand(g_v, BIGVECSIZE);
// printf("u = "); printvec(g_u, BIGVECSIZE);
// printf("v = "); printvec(g_v, BIGVECSIZE);
time_t t1 = time(NULL);
double r;
for (int i = 0; i < 500; i++)
r = dot(g_u, g_v, BIGVECSIZE);
time_t t2 = time(NULL);
printf("[S] u . v = %g (%lds)\n", r, (long)(t2-t1));
time_t t3 = time(NULL);
double r2;
for (int i = 0; i < 500; i++)
r2 = mt_dot(g_u, g_v, BIGVECSIZE);
time_t t4 = time(NULL);
printf("[T] u . v = %g (%lds)\n", r2, (long)(t4-t3));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment