mhche Δημοσιεύτηκε Ιανουάριος 23, 2013 #1 Κοινοποίηση Δημοσιεύτηκε Ιανουάριος 23, 2013 Καλημέρα, μήπως ξέρει κάνεις αν υπάρχει κάπου ο κώδικας της multithreaded merge sort σε c.Ή αν μπορεί να με βοηθήσει κάποιος.Ευχαριστώ πολύ, Link to comment Share on other sites More sharing options...
nucleus Ιανουάριος 23, 2013 #2 Κοινοποίηση Ιανουάριος 23, 2013 *I, ME AND MYSELF !!!: Threaded Merge Sortμε POSIX threads. Link to comment Share on other sites More sharing options...
mhche Ιανουάριος 23, 2013 Author #3 Κοινοποίηση Ιανουάριος 23, 2013 *I, ME AND MYSELF !!!: Threaded Merge Sortμε POSIX threads.Ευχαριστώ πολύ,αλλά νομίζω πως οι γνώσεις μου απέχουν απ'αυτό.Προσπαθώ να φτιάξω κάτι τέτοιο,όπου θα δημιουργώ δύο πίνακες με τυχαίες τιμές και έπειτα με πολυνηματική mergesort να τους ταξινομώ.Ο παρακάτω κώδικας μου βγάζει segmentation fault(core dumped)#include <pthread.h>#include <stdlib.h>#include <stdio.h>#include <math.h>#define NUM_THREADS 2int* x;int* y; //sorted arrayint n;struct index{int p,r;};void* merge_sort(void* param){ struct index* pr = (struct index*) param; int p = pr->p, r = pr->r , ret1,ret2; if (p==r) pthread_exit(0); pthread_t thread1,thread2; struct index pr1,pr2; int q = (p+r)/2; pr1.p = p; pr1.r = q; pr2.p = q+1; pr2.r = r; ret1 = pthread_create(&thread1,NULL,merge_sort,(void*) &pr1); if (ret1>0) printf("failed to create new thread 1\n"); ret2 = pthread_create(&thread2,NULL,merge_sort,(void*) &pr2); if (ret2>0) printf("failed to create new thread 2\n"); pthread_join(thread1,NULL); pthread_join(thread2,NULL); int k = p ,i = p ,j = q+1; while (i<=q && j<=r){ if (x[i] < x[j]) y[k++] = x[i++]; else y[k++] = x[j++]; } for (; i<=q ; i++) y[k++] = x[i]; for (; j<=r ; j++) y[k++] = x[j]; for (i= p ; i <= r ;i++) x[i] = y[i]; pthread_exit(0); return NULL;}int main(){# define SIZE 16384 int i, A[SIZE],B[SIZE]; for (i = 0; i < SIZE; i++){ A[i] = rand() % 10000; B[i] = rand() % 10000; } merge_sort(A); merge_sort(; printf("after sort A: %d ", A[18],'\n'); printf("after sort B: %d ", B[165],'\n'); return 0;} Link to comment Share on other sites More sharing options...
nucleus Ιανουάριος 23, 2013 #4 Κοινοποίηση Ιανουάριος 23, 2013 # define SIZE 16384Preprocessor directive μέσα στην main *slap* :S.Αυτό είναι σε λάθος σημείο πρέπει να μπει μαζί με το άλλο define που έχεις στην αρχή εκτός και αν το έχεις ήδη διορθώσει οπότε συγνώμη για το slap.Μήπως τα pr1 και pr2 πρέπει να είναι πίνακες με δομές τύπου index?Επίσης είσαι σίγουρος ότι τα 2 printf δουλεύουν σωστά? Link to comment Share on other sites More sharing options...
mhche Ιανουάριος 23, 2013 Author #5 Κοινοποίηση Ιανουάριος 23, 2013 # define SIZE 16384Preprocessor directive μέσα στην main *slap* :S.Αυτό είναι σε λάθος σημείο πρέπει να μπει μαζί με το άλλο define που έχεις στην αρχή εκτός και αν το έχεις ήδη διορθώσει οπότε συγνώμη για το slap. Μήπως τα pr1 και pr2 πρέπει να είναι πίνακες με δομές τύπου index? Επίσης είσαι σίγουρος ότι τα 2 printf δουλεύουν σωστά? Δεν είναι λάθος το define στη main, όσο και αν θες να με *slap* Ούτε τα pr είναι λάθος,τα printf δεν έχουν κάποια σχέση,περισσότερο αναγνωριστικά είναι. Το λάθος είναι όταν καλώ την merge_sort,ώστε να ταξινομηθεί ο πίνακας. Στην αρχή τα int* x,int* y εκεί κάτι γίνεται λάθος,μάλλον κάνει stack overflow γιαυτό περνω και το λάθος. Link to comment Share on other sites More sharing options...
nucleus Ιανουάριος 23, 2013 #6 Κοινοποίηση Ιανουάριος 23, 2013 Δεν έχεις κάνει πουθενά malloc για τα x και y.Δοκίμασε και μην ξεχάσεις και την free πάντα όταν τελειώσεις με τα x και yΕπίσης αφού κάνεις pthread_join γιατί κάνεις και pthread_exit(0)? Βγάλε το pthread_exit(0) Link to comment Share on other sites More sharing options...
mhche Ιανουάριος 23, 2013 Author #7 Κοινοποίηση Ιανουάριος 23, 2013 Δεν έχεις κάνει πουθενά malloc για τα x και y.Δοκίμασε και μην ξεχάσεις και την free πάντα όταν τελειώσεις με τα x και yΕπίσης αφού κάνεις pthread_join γιατί κάνεις και pthread_exit(0)? Βγάλε το pthread_exit(0)malloc γιατί,αφου στην συνάρτηση μου υπάρχουν αυτά, τι να κάνω malloc όλη την συνάρτηση;αν δεν κάνω pthread_exit(0) θα μου κρατάει την flag απ το thread πάνω στην ουσία,δλδ θα το χω κλειδωμένοΝομίζω πως η συνάρτηση μου δεν είναι δυναμική,μάλλον αυτό πρέπει να ναι το λάθος.Ο,τι παίρνει καρφωτά τα x,y και δεν μου προσφέρει τίποτα στην ουσία. Link to comment Share on other sites More sharing options...
nucleus Ιανουάριος 23, 2013 #8 Κοινοποίηση Ιανουάριος 23, 2013 Τα x και y είναι πίνακες int οπότε πρέπει να κάνεις malloc μέσα στην merge_sort για να έχουν το σωστό μέγεθος το οποίο είναι δυναμικό.Ποιό flag?Αφού κάνεις join δεν χρειάζεται το pthread_exit πριν το return δοκίμασε το.Σίγουρα η υλοποίηση του merge sort που χρησιμοποιείς δουλεύει σωστά? Link to comment Share on other sites More sharing options...
mhche Ιανουάριος 23, 2013 Author #9 Κοινοποίηση Ιανουάριος 23, 2013 Τα x και y είναι πίνακες int οπότε πρέπει να κάνεις malloc μέσα στην merge_sort για να έχουν το σωστό μέγεθος το οποίο είναι δυναμικό.Ποιό flag?Αφού κάνεις join δεν χρειάζεται το pthread_exit πριν το return δοκίμασε το. Σίγουρα η υλοποίηση του merge sort που χρησιμοποιείς δουλεύει σωστά? Μάλλον η τελευταία ερώτηση σου είναι και το λάθος Εγκατέλειψα την προηγούμενη προσπάθεια,και είμαι σε μια πιο απλή που δουλεύει #include <pthread.h>#include <stdlib.h>#include <stdio.h>//#define NUM_THREADS 2#define size 16384//pthread_t thread[NUM_THREADS];//pthread_mutex_t UpdateMutex;void MERGE (int low,int mid,int high, int* a){ int h,i,j,k; int b[size]; h=low; i=low; j=mid+1; while ((h<=mid)&&(j<=high)){ if (a[h]<=a[j]){ b[i]=a[h]; h++;} else { b[i]=a[j]; j++;} i++;} if(h>mid) { for (k=j;k<=high;k++){ b[i]=a[k]; i=i+1;} } else { for(k=h;k<=mid;k++){ b[i]=a[k]; i++;} } for(k=low;k<=high;k++) {a[k]=b[k];}}void MERGESORT(int low,int high,int* a){ //pthread_mutex_lock (&UpdateMutex); int mid; if (low<high) { mid=(low+high)/2; MERGESORT(low,mid,a); MERGESORT(mid+1,high,a); MERGE(low,mid,high,a); } //pthread_mutex_unlock(&UpdateMutex);}int main (){int i;int A[16384],B[16384];for (i=0;i<size;i++){A[i] = rand() %10000;B[i] = rand() %10000; }MERGESORT(0,size,A);MERGESORT(0,size,;printf("A %i\n",A[1383]); printf("B %i\n",B[1633]);return 0;} Το θέμα εδώ είναι, πως δεν ξέρω ακόμα πως να βάλω σωστά τα νήματα. Link to comment Share on other sites More sharing options...
nucleus Ιανουάριος 23, 2013 #10 Κοινοποίηση Ιανουάριος 23, 2013 Mέσα στην void MERGESORT(int low,int high,int* a)Θα φτιάχνεις 2 νήματα που το καθένα θα εκτελεί μια αναδρομική κλήση της MERGESORTΚαι το ερώτημα που αφήνετε σαν άσκηση στον αναγνώστη είναι.Πρέπει ή όχι να αλλαχθεί και η θέση της MERGE(low,mid,high,a) και αν ναι που πρέπει να πάει? Link to comment Share on other sites More sharing options...
mhche Ιανουάριος 23, 2013 Author #11 Κοινοποίηση Ιανουάριος 23, 2013 Mέσα στην void MERGESORT(int low,int high,int* a)Θα φτιάχνεις 2 νήματα που το καθένα θα εκτελεί μια αναδρομική κλήση της MERGESORT Και το ερώτημα που αφήνετε σαν άσκηση στον αναγνώστη είναι. Πρέπει ή όχι να αλλαχθεί και η θέση της MERGE(low,mid,high,a) και αν ναι που πρέπει να πάει? Μπορώ να αφήσω πολλά περισσότερα ερωτήματα,απο τόσο κάτι απλό Λοιπόν, #include <pthread.h>#include <stdlib.h>#include <stdio.h>#define NUM_THREADS 2#define size 16384pthread_t thread[NUM_THREADS];pthread_mutex_t UpdateMutex;int A[size],B[size];void *merge(int low,int mid,int high, int* a){ int h,i,j,k; int temp[size]; h=low; i=low; j=mid+1; while ((h<=mid)&&(j<=high)){ if (a[h]<=a[j]){ temp[i]=a[h]; h++;} else { temp[i]=a[j]; j++;} i++;} if(h>mid) {for (k=j;k<=high;k++){ temp[i]=a[k]; i=i+1;}} else {for(k=h;k<=mid;k++){temp[i]=a[k]; i++;}} for(k=low;k<=high;k++) {a[k]=temp[k];}}void *mergesort(int low,int high,int *arg) { int i,id,mid; id= *(int *) arg; for ( i=id * (size/NUM_THREADS); i<(id+1)*(size/NUM_THREADS); i++ ) { pthread_mutex_lock(&UpdateMutex); if (low<high) { mid=(low+high)/2; mergesort(low,mid,arg); mergesort(mid+1,high,arg); merge(low,mid,high,arg); } pthread_mutex_unlock(&UpdateMutex); } return NULL;}void *mymerge(void *arg) { int i; for (i=0; i<NUM_THREADS; i++) pthread_create(&thread[i], NULL, mergesort(0,size,,&arg); for (i=0; i<NUM_THREADS; i++) pthread_join(thread[i], NULL);}int main (){ int i,j;for (i=0;i<100;i++){ A[i] = rand() %10000; B[i] = rand() %10000;}pthread_mutex_init (&UpdateMutex, NULL);pthread_create(&thread[NUM_THREADS], NULL, mymerge, NULL); printf("A1 %i\n", B[0]);return 0;} Έφτιαξα αυτό,όπως φαίνεται όμως εδώ pthread_create(&thread, NULL, mergesort(0,size,,&arg); πάει για τον έναν πίνακα πως θα το κάνω για οποιονδήποτε; Link to comment Share on other sites More sharing options...
nucleus Ιανουάριος 23, 2013 #12 Κοινοποίηση Ιανουάριος 23, 2013 Θα τον περάσεις σαν όρισμα στην mymerge Link to comment Share on other sites More sharing options...
chameleon Φεβρουάριος 3, 2013 #13 Κοινοποίηση Φεβρουάριος 3, 2013 Αφήστε ρε τα PThreads για τέτοιες απλές εργασίες.Δοκίμασε OpenMPΕίναι εύκολο στο στήσιμο.Υποστηρίζεται απ' όλους τους σοβαρούς compilers (προφανώς και gcc) και σε περίπτωση που κάποιος δεν το υποστηρίζει απλά τρέχει σαν single threaded.Πόσο απλός ο κώδικας;Τόσο:#omp parallel forfor(int i = 0; i < SIZE; i++) ....Αυτόματα ο compiler γράφει κώδικα και δημιουργεί τόσα threads όσα είναι και τα core του επεξεργαστή σου.Super Cool?Ναι. Και δεν αλλάζεις τίποτα από κώδικα. Απλά προσθέτεις την ντιρεκτίβα #omp parallel for Link to comment Share on other sites More sharing options...
chameleon Φεβρουάριος 3, 2013 #14 Κοινοποίηση Φεβρουάριος 3, 2013 Τα πρώτα πολύ απλά παραδείγματα, που όμως σε καλύπτουν 100% σε αυτό που θέλεις να κάνεις, θα τα βρεις στη Wikipedia.OpenMP - Wikipedia, the free encyclopedia Link to comment Share on other sites More sharing options...
mhche Φεβρουάριος 3, 2013 Author #15 Κοινοποίηση Φεβρουάριος 3, 2013 Αφήστε ρε τα PThreads για τέτοιες απλές εργασίες.Δοκίμασε OpenMPΕίναι εύκολο στο στήσιμο.Υποστηρίζεται απ' όλους τους σοβαρούς compilers (προφανώς και gcc) και σε περίπτωση που κάποιος δεν το υποστηρίζει απλά τρέχει σαν single threaded.Πόσο απλός ο κώδικας;Τόσο:#omp parallel forfor(int i = 0; i < SIZE; i++) ....Αυτόματα ο compiler γράφει κώδικα και δημιουργεί τόσα threads όσα είναι και τα core του επεξεργαστή σου.Super Cool?Ναι. Και δεν αλλάζεις τίποτα από κώδικα. Απλά προσθέτεις την ντιρεκτίβα #omp parallel forΤα πρώτα πολύ απλά παραδείγματα, που όμως σε καλύπτουν 100% σε αυτό που θέλεις να κάνεις, θα τα βρεις στη Wikipedia.OpenMP - Wikipedia, the free encyclopediaΣε ευχαριστώ για την απάντηση σου, πραγματικά χρήσιμο. Απλά αυτός ήταν ο σκοπός της εργασίας που ήθελα να κάνω. Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.