2012-03-21 11 views
6

के अंदर स्मृति आवंटन मेरे पास कर्नेल का निम्न (स्निपेट) है।एक CUDA कर्नेल

__global__ void plain(int* geneVec, float* probs, int* nComponents, float* randomNumbers,int *nGenes) 
{ 

    int xid = threadIdx.x + (blockDim.x * blockIdx.x); 

    float* currentProbs= (float*)malloc(sizeof(float)*tmp); 

     ..... 
     ..... 

    currentProbs[0] = probs[start]; 
    for (k=1;k<nComponents[0]; k++) 
    { 
     currentProbs[k] = currentProbs[k-1] + prob; 
    } 

     ... 
     ... 
     free(currentProbs); 

} 

जब यह स्थिर (यहां तक ​​कि एक ही आकार) है वह बहुत तीव्र है, लेकिन जब CurrentProbs गतिशील (ऊपर) के रूप में आवंटित किया जाता है प्रदर्शन भयानक है।

इस सवाल ने कहा कि मैं एक कर्नेल के अंदर ऐसा कर सकता है: Efficiency of Malloc function in CUDA

यदि कोई अन्य तरीकों पत्र में प्रस्तावित एक से यह अन्य समाधान कर लिया है मैं सोच रहा था: CUDA allocate memory in __device__ function

यहाँ एक संबंधित सवाल है? यह हास्यास्पद लगता है कि इस तरह के जुर्माना के बिना कोई कर्नेल के अंदर malloc/free नहीं कर सकता है।

+0

आपके छद्म कोड में 'tmp' कहां से आता है? – talonmies

+0

क्षमा करें - tmp = ncomponents [0]; –

+0

तो यह प्रति कर्नेल आमंत्रण निरंतर है? यदि हां, तो डायनामिक मेमोरी आवंटन से परेशान क्यों हो? – talonmies

उत्तर

7

मुझे लगता है कि मॉलोक() को शुरू करने का कारण आपके कोड को धीमा कर देता है यह है कि यह वैश्विक स्मृति में स्मृति आवंटित करता है। जब आप एक निश्चित आकार सरणी का उपयोग करते हैं, तो संकलक इसे रजिस्टर फ़ाइल में डाल सकता है, जो बहुत तेज है।

अपने कर्नेल के अंदर एक मॉलोक करने के लिए इसका मतलब यह हो सकता है कि आप एक कर्नेल के साथ बहुत अधिक काम करने की कोशिश कर रहे हैं। यदि प्रत्येक थ्रेड मेमोरी की एक अलग मात्रा आवंटित करता है, तो प्रत्येक थ्रेड लूप में अलग-अलग बार चलाता है, और आपको बहुत सारे विचलन मिलते हैं।

यदि एक तार में प्रत्येक थ्रेड एक ही संख्या में लूप चलाता है, तो बस सामने आवंटित करें। यहां तक ​​कि यदि वे अलग-अलग समय चलाते हैं, तो आप निरंतर आकार का उपयोग कर सकते हैं। लेकिन इसके बजाय, मुझे लगता है कि आपको यह देखना चाहिए कि आप अपने कर्नेल से उस लूप को पूरी तरह से हटाने के लिए अपने कोड को कैसे दोबारा कर सकते हैं।

+1

संकलक कभी भी स्मृति स्मृति में कर्नेल चर निर्दिष्ट नहीं करेगा जब तक कि प्रोग्रामर उन्हें '__shared__' क्वालीफायर का उपयोग करके परिभाषित नहीं करता। केवल पंजीयक या स्थानीय स्मृति। – talonmies

+0

@talonmies: स्पष्टीकरण के लिए धन्यवाद। मैंने जवाब संपादित कर लिया है। –

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^