#include #include #include #include #define NELEMENTS 1024*1024*16 #define NTHREADS 8 typedef struct { unsigned int thread_ID; float* pvecA; float* pvecB; float* pvecC; } argumenti_t; pthread_t nit[NTHREADS]; void* funkcija_niti(void* arg); void* (*pfunkcija_niti)(void*); argumenti_t args[NTHREADS]; float* pvecA; float* pvecB; float* pvecC; /* timespec is a struct defined in ctime as * struct timespec { * time_t tv_sec; // seconds * long tv_nsec; // nanoseconds * }; */ struct timespec timeStart, timeEnd; int main(){ pfunkcija_niti = funkcija_niti; // dinamično ustvarim 3 velike vektorje v pomnilniku pvecA = (float*)malloc(NELEMENTS*sizeof(float)); pvecB = (float*)malloc(NELEMENTS*sizeof(float)); pvecC = (float*)malloc(NELEMENTS*sizeof(float)); // init vektorjev A in B: for (int i = 0; i < NELEMENTS; i++) { *(pvecA + i) = 2.0; pvecB[i] = 3.0; } for (int i = 0; i < NTHREADS; i++) { args[i].thread_ID = i; args[i].pvecA = pvecA; args[i].pvecB = pvecB; args[i].pvecC = pvecC; pthread_create(&(nit[i]), // kazalec na nit, ki jo ustvarjamo NULL, pfunkcija_niti, // funkcija, ki jo izvede ustvarjena nit (void*) &args[i]); // argumenti funkcije, ki jo izvede ustvarjena nit - // edini argument je navaden void naslov, zato moram naslov na strukturo args1 // pretvorit v navaden void naslov } clock_t start = clock(); clock_gettime(CLOCK_REALTIME, &timeStart); // Počakajmo , da se vse niti zaključijo. V ta namen uporabim funkcijo join: for (int i = 0; i < NTHREADS; i++) { pthread_join(nit[i], NULL); } // šele sedaj je varno zaključiti main(). // preverimo rezultat: float rezultat = 0.0; for (int i = 0; i < NELEMENTS; i++) { rezultat += pvecC[i]; } clock_gettime(CLOCK_REALTIME, &timeEnd); clock_t end = clock(); double time_taken = ((double)(end-start))/CLOCKS_PER_SEC; // calculate the elapsed time double elapsed_time = (timeEnd.tv_sec - timeStart.tv_sec) + (timeEnd.tv_nsec - timeStart.tv_nsec) / 1e9; // in seconds printf("Čas izvajanja: %f sekund \n", time_taken); printf("Čas izvajanja: %f sekund \n", elapsed_time); printf("Rezultat = %f \n", rezultat); free(pvecA); free(pvecB); free(pvecC); return 0; } void* funkcija_niti(void* arg){ // argument arg je navaden void nasalov, ki ga želim uporabiti za dostop do elementov strukture, na katero kaže. // Zato moram definirati nov kazalec na sterukturo in argument castat na ta tip argumenti_t* argumenti = (argumenti_t*) arg; for (int i = argumenti->thread_ID * (NELEMENTS/NTHREADS); i < (argumenti->thread_ID + 1) * (NELEMENTS/NTHREADS); i++) { argumenti->pvecC[i] = argumenti->pvecA[i] + argumenti->pvecB[i]; } }