#include #include #include #include #include //#define SMALL_TEST #ifdef SMALL_TEST #define N 9 #else #define N 39 #endif #define T 4 #define ROUND(x) (int)(x+0.5) #ifdef SMALL_TEST unsigned int seznam[] = {7,4,3,6,5,2,8,9,1}; #else unsigned int seznam[N]; #endif //unsigned int *pSeznam = &seznam[0]; unsigned int *pSeznam = seznam; int iBlockSize = N/T; typedef struct{ int myID; unsigned int *pMySeznam; int iSize; } thread_args_t; pthread_t nit[T]; pthread_barrier_t barrier; thread_args_t args[T]; /* timespec is a struct defined in ctime as * struct timespec { * time_t tv_sec; // seconds * long tv_nsec; // nanoseconds * }; */ struct timespec timeStart, timeEnd; void* funkcija_niti(void* args); void* (*pFunkcijaNiti)(void*) = funkcija_niti; void izpisi_seznam(unsigned int *pSeznam){ for (int i = 0; i < N; i++) { printf("%d ", *(pSeznam+i)); } printf("\n"); } void primerjaj_in_zamenjaj(unsigned int* a, unsigned int* b){ unsigned int temp; if (*b < *a) { temp = *a; *a = *b; *b = temp; } } void sodi_prehod(int iEnd, unsigned int* pSeznam){ for (int i = 0; i < iEnd; i=i+2){ primerjaj_in_zamenjaj(&pSeznam[i], &pSeznam[i+1]); } } void lihi_prehod(int iEnd, unsigned int* pSeznam){ for (int i = 1; i < iEnd; i=i+2){ primerjaj_in_zamenjaj(&pSeznam[i], &pSeznam[i+1]); } } int main(){ #ifndef SMALL_TEST //init seznama: for(int i = 0; i < N; i++){ seznam[i] = rand() % (100); } #endif izpisi_seznam(pSeznam); pthread_barrier_init(&barrier, NULL, T); clock_gettime(CLOCK_REALTIME, &timeStart); for(int i = 0; i < T; i++){ args[i].myID = i; args[i].pMySeznam = pSeznam + (i*(N/T)); if (args[i].myID < T-1) args[i].iSize = N/T; //else args[i].iSize = ROUND(((float)N/(float)T)) - 1; else args[i].iSize = (N/T) + (N%T) - 1; pthread_create( &nit[i], NULL, pFunkcijaNiti, (void *) &args[i]); } for(int i = 0; i < T; i++){ pthread_join(nit[i], NULL); } clock_gettime(CLOCK_REALTIME, &timeEnd); double elapsed_time = (timeEnd.tv_sec - timeStart.tv_sec) + (timeEnd.tv_nsec - timeStart.tv_nsec) / 1e9; pthread_barrier_destroy(&barrier); izpisi_seznam(pSeznam); printf("Čas izvajanja: %f sekund \n", elapsed_time); } void* funkcija_niti(void* args){ thread_args_t* pArgumenti = (thread_args_t*)args; //printf("Nit %d, pSeznam=%p, prvi element=%d \n", pArgumenti->myID, pArgumenti->pMySeznam, *(pArgumenti->pMySeznam)); //pthread_barrier_wait(&barrier); for (int i = 0; i < N; i++) { sodi_prehod(pArgumenti->iSize, pArgumenti->pMySeznam); pthread_barrier_wait(&barrier); lihi_prehod(pArgumenti->iSize, pArgumenti->pMySeznam); pthread_barrier_wait(&barrier); } } /* PARALELIZACIJA: - več niti dela en sam prehod - vsaka nit dobi en kos seznama - med prehodi se morajo niti počakati na barieri - Bariere: deklaracija: pthread_barrier_t prepreka; inizializacija: pthread_barrier_init(&prepreka, NULL, stevilo_niti); čakanje na prepreki: vsaka nit kliče pthread_barrier_wait(); na koncu programe: pthread_barrier_destroy(&prepreka); */