सी

2011-12-31 7 views
11

में समांतर quicksort सी में समानांतर quicksort के कार्यान्वयन के लिए बहुत सी खोज के बाद, मैं इसे गोता लगाने और इसे कोड करने वाला हूं। (मैं लगभग 1 लाख पाठ स्ट्रिंग्स की एक सरणी सॉर्ट करने के लिए की जरूरत है।) ऐसा लगता है कि सभी कार्यान्वयन मैं पाया है qsort समारोह में ही है, जो धागा प्रति कार्य की छोटी राशि विभाजन में भूमि के ऊपर की एक बड़ी राशि बनाता है अंदर काम को विभाजित ।सी

धागे की संख्या (मेरे मामले में, 24 धागे) द्वारा 1 मिलियन तारों को विभाजित करने के लिए यह बहुत तेज़ नहीं होगा, और उन्हें प्रत्येक अनुभाग को एक अनुभाग पर रखें, और फिर एक विलय करें? माना जाता है कि इसमें सैद्धांतिक नुकसान है कि यह एक जगह नहीं है, लेकिन स्मृति की उपलब्धियों के साथ यह कोई समस्या नहीं है। जिस मशीन पर यह चल रहा है वह 12 (बहुत तेज़) भौतिक/24 लॉजिकल कोर और 1 9 2 जीबी (हाँ, गीगाबाइट) मेमोरी है। वर्तमान में, इस मशीन पर भी, लगभग 8 मिनट लगते हैं!

+0

शायद। निर्भर करता है। समस्या पर हार्डवेयर पर – Anycorn

+0

http://en.wikipedia.org/wiki/Quicksort#Parallelization –

+0

http://en.wikipedia.org/wiki/External_sorting –

उत्तर

8

यह (24 धागे मेरे मामले में,) धागे की संख्या से 1 लाख तार विभाजित करने के लिए बहुत तेजी से नहीं होगा, और उन्हें एक खंड पर प्रत्येक कार्य है, और तो एक mergesort करना ?

यह एक अच्छा विचार है।

लेकिन आपऔर merge-sort के लिए खिलौना कार्यक्रम लिखकर कुछ अवलोकन कर सकते हैं और उनके एल्गोरिदमिक/रन-टाइम-व्यवहार के फायदे ले सकते हैं।

उदाहरण के लिए। quick-sort प्रकार dividing प्रक्रिया (pivot तत्व उस पुनरावृत्ति के अंत में अपने अंतिम स्थान पर रखा जाएगा) और merge-sort प्रकार merging (पूरे कार्य-सेट को तोड़ने (विभाजित) बहुत दानेदार इकाइयों में विभाजित करने के बाद किया जाता है जहां यह किया जाता है सीधे अन्य बारीक-इकाइयों (== या strcmp()) के साथ तुलना की जा सकती।

वर्किंग सेट की प्रकृति के आधार एल्गोरिदम अप मिश्रण एक अच्छा विचार है।

समानांतर छंटाई के संबंध में

, यहाँ मेरी parallel merge-sort है आप आरंभ करने के लिए के लिए।

#include <stdio.h> 
#include <pthread.h> 
#include <stdlib.h> 

#define NOTHREADS 2 

/* 

gcc -ggdb -lpthread parallel-mergesort.c 


NOTE: 
The mergesort boils downs to this.. 
Given two sorted array's how do we merge this? 

We need a new array to hold the result of merging 
otherwise it is not possible to do it using array, 
so we may need a linked list 

*/ 

int a[] = {10, 8, 5, 2, 3, 6, 7, 1, 4, 9}; 

typedef struct node { 
int i; 
int j; 
} NODE; 

void merge(int i, int j) 
{ 
     int mid = (i+j)/2; 
     int ai = i; 
     int bi = mid+1; 

     int newa[j-i+1], newai = 0; 

     while(ai <= mid && bi <= j) { 
       if (a[ai] > a[bi]) 
         newa[newai++] = a[bi++]; 
       else      
         newa[newai++] = a[ai++]; 
     } 

     while(ai <= mid) { 
       newa[newai++] = a[ai++]; 
     } 

     while(bi <= j) { 
       newa[newai++] = a[bi++]; 
     } 

     for (ai = 0; ai < (j-i+1) ; ai++) 
       a[i+ai] = newa[ai]; 

} 

void * mergesort(void *a) 
{ 
       NODE *p = (NODE *)a; 
       NODE n1, n2; 
       int mid = (p->i+p->j)/2; 
       pthread_t tid1, tid2; 
       int ret; 

       n1.i = p->i; 
       n1.j = mid; 

       n2.i = mid+1; 
       n2.j = p->j; 

       if (p->i >= p->j) return; 

       ret = pthread_create(&tid1, NULL, mergesort, &n1); 
       if (ret) { 
         printf("%d %s - unable to create thread - ret - %d\n", __LINE__, __FUNCTION__, ret);  
         exit(1); 
       } 


       ret = pthread_create(&tid2, NULL, mergesort, &n2); 
       if (ret) { 
         printf("%d %s - unable to create thread - ret - %d\n", __LINE__, __FUNCTION__, ret);  
         exit(1); 
       } 

       pthread_join(tid1, NULL); 
       pthread_join(tid2, NULL); 

       merge(p->i, p->j); 
       pthread_exit(NULL); 
} 


int main() 
{ 
       int i; 
       NODE m; 
       m.i = 0; 
       m.j = 9; 
       pthread_t tid; 

       int ret; 

       ret=pthread_create(&tid, NULL, mergesort, &m); 
       if (ret) { 
         printf("%d %s - unable to create thread - ret - %d\n", __LINE__, __FUNCTION__, ret);  
         exit(1); 
       } 

       pthread_join(tid, NULL); 

       for (i = 0; i < 10; i++) 
           printf ("%d ", a[i]); 

       printf ("\n"); 

       // pthread_exit(NULL); 
       return 0; 
} 

गुड लक!

3

क्विक्सोर्ट में एक सूची में प्रारंभिक पास शामिल है, जो सूची को उच्चतम और पिवट से कम वर्गों में सूचीबद्ध करता है।

क्यों एक धागे में ऐसा नहीं करते हैं, और फिर एक और धागा पैदा करते हैं और इसे एक आधे हिस्से में सौंपते हैं जबकि मौजूदा धागे दूसरे आधे भाग लेते हैं, और इतने पर और आगे?

1

क्या आपने विशेष रूप से स्ट्रिंग को सॉर्ट करने के लिए डिज़ाइन किए गए सॉर्टिंग एल्गोरिदम का उपयोग करने पर विचार किया है? ऐसा लगता है कि कस्टम क्विकॉर्ट को कार्यान्वित करने की कोशिश करने से यह एक बेहतर विचार हो सकता है। एल्गोरिदम की विशिष्ट पसंद शायद तारों की लंबाई पर निर्भर करती है और वे कितनी अलग हैं लेकिन radix sort शायद खराब शर्त नहीं है।

एक त्वरित google search तारों को सॉर्ट करने के बारे में an article चालू हुआ। मैंने इसे पढ़ा नहीं है लेकिन सेडगेविक और बेंटले वास्तव में उनकी सामग्री को जानते हैं। सार के मुताबिक, उनके एल्गोरिदम क्विक्सोर्ट और रेडिक्स सॉर्ट का एक मिश्रण है।

एक और संभावित समाधान सी ++ से समांतर सॉर्टिंग एल्गोरिदम लपेटना है।जीएनयू के एसटीएल कार्यान्वयन में parallel mode है, जिसमें समानांतर क्विकॉर्ट कार्यान्वयन शामिल है। यह शायद सबसे आसान समाधान है।

+0

यह एक शानदार लिंक है। ऐसा लगता है कि वे तारों को क्रमबद्ध करने के लिए उपयोग किए जाने वाले अलगो कम से कम 2x जितनी तेजी से qsort के रूप में होते हैं। समानांतर बनाने के लिए थोड़ा बालों को दिखता है, इसलिए यह भविष्य की परियोजना होगी। – PaeneInsula

0

बहु-थ्रेडेड क्विकॉर्ट को व्यवहार्य मेमोरी एक्सेस बनाने के लिए अनुकूलित करने की आवश्यकता है ताकि अधिकांश सॉर्टिंग कार्य गैर-साझा कैश (एल 1 & एल 2) के अंदर किया जा सके। मेरी शर्त यह है कि एकल-थ्रेडेड क्विकॉर्ट मुली-थ्रेडेड से तेज़ होगा जबतक कि आप काम की भारी मात्रा में डालने के लिए तैयार न हों।

परीक्षण के लिए एक दृष्टिकोण ऊपरी आधा और दूसरे को क्रमबद्ध करने के लिए एक धागा हो सकता है।

एक विशेष स्ट्रिंग-अनुकूलित सॉर्टिंग दिनचर्या के रूप में अवधारणा मेरे लिए अजीब लगती है। मेरा मतलब है कि ऐसे कई मामले नहीं हैं जहां केवल तारों (या पूर्णांक) के वेक्टर को सॉर्ट करना विशेष रूप से उपयोगी होता है। आम तौर पर डेटा कॉलम और पंक्तियों वाली तालिका में व्यवस्थित किया जाएगा और आप पंक्तियों को एक कॉलम से क्रमबद्ध करना चाहते हैं, और यदि वे बराबर हैं, तो आप एक अतिरिक्त कॉलम का उपयोग करके एक टाइम स्टैम्प या रैंकिंग वाले सॉर्ट करेंगे या कुछ और। तो क्रमबद्ध दिनचर्या एक बहु-स्तरीय सॉर्ट नियम सेट को संभालने में सक्षम होना चाहिए जो तालिका के कॉलम में मौजूद किसी भी दिशा (आरोही या अवरोही) में किसी भी प्रकार का डेटा (बूलियन, पूर्णांक, तिथियां, तार, फ़्लोटिंग पॉइंट इत्यादि) निर्दिष्ट कर सकता है।