2008-11-14 10 views
5

मैं एक CUDA कर्नेल जो मैं किसी विशेष झंडे के बिना एक cubin फाइल करने के लिए संकलन कर रहा हूँ है:CUDA स्मृति परेशानी पैदा करती

nvcc text.cu -cubin 

यह संकलित हालांकि इस संदेश के साथ:

सलाह: नहीं बता सकते हैं ग्लोबल मेमोरी स्पेस

और कुछ अस्थायी सीपीपी फ़ाइल में एक पंक्ति का संदर्भ मानने के लिए क्या सूचक इंगित करता है। मैं इसे कुछ प्रतीत होता है मनमाने ढंग से कोड पर टिप्पणी करके काम करने के लिए यह प्राप्त कर सकता है जो मुझे कोई समझ नहीं आता है।

__global__ void string_search(char** texts, int* lengths, char* symbol, int* matches, int symbolLength) 
{ 
    int localMatches = 0; 
    int blockId = blockIdx.x + blockIdx.y * gridDim.x; 
    int threadId = threadIdx.x + threadIdx.y * blockDim.x; 
    int blockThreads = blockDim.x * blockDim.y; 

    __shared__ int localMatchCounts[32]; 

    bool breaking = false; 
    for(int i = 0; i < (lengths[blockId] - (symbolLength - 1)); i += blockThreads) 
    { 
     if(texts[blockId][i] == symbol[0]) 
     { 
      for(int j = 1; j < symbolLength; j++) 
      { 
       if(texts[blockId][i + j] != symbol[j]) 
       { 
        breaking = true; 
        break; 
       } 
      } 
      if (breaking) continue; 
      localMatches++; 
     } 
    } 

    localMatchCounts[threadId] = localMatches; 

    __syncthreads(); 

    if(threadId == 0) 
    { 
     int sum = 0; 
     for(int i = 0; i < 32; i++) 
     { 
      sum += localMatchCounts[i]; 
     } 
     matches[blockId] = sum; 
    } 
} 

अगर मैं इस लाइन

localMatchCounts[threadId] = 5; 

यह कोई नोटिस के साथ संकलित के साथ लाइन

localMatchCounts[threadId] = localMatches; 
पाश के लिए पहले के बाद

बदल देते हैं:

गिरी इस प्रकार है। यह लाइन के ऊपर लूप के प्रतीत होता है यादृच्छिक भागों पर टिप्पणी करके भी हासिल किया जा सकता है। मैंने स्थानीय मेमोरी सरणी को सामान्य सरणी के साथ किसी भी प्रभाव के लिए बदलने की भी कोशिश की है। क्या कोई मुझे बता सकता है कि समस्या क्या है?

सिस्टम Vista के 64 बिट है, इसकी कीमत क्या है।

संपादित करें: मैंने कोड तय किया है, इसलिए यह वास्तव में काम करता है, हालांकि यह अभी भी कंपाइलर नोटिस उत्पन्न करता है। ऐसा प्रतीत नहीं होता है कि चेतावनी एक समस्या है, कम से कम शुद्धता के संबंध में (यह प्रदर्शन को प्रभावित कर सकती है)।

उत्तर

1

char ** जैसे पॉइंटर्स की Arrays कर्नेल में समस्याग्रस्त हैं, क्योंकि कर्नेल के पास होस्ट की स्मृति तक कोई पहुंच नहीं है।
एक निरंतर बफर आवंटित करना और समानांतर पहुंच को सक्षम करने के तरीके को विभाजित करना बेहतर है।
इस मामले मैं एक 1 डी सरणी जो सभी स्ट्रिंग्स एक और और एक अन्य -1 डी सरणी के बाद एक तैनात होते हैं, आकार 2 * numberOfStrings जो यह की दूरी पहली सरणी के भीतर प्रत्येक स्ट्रिंग की भरपाई और शामिल निर्धारित करेंगे में:

के लिए उदाहरण - कर्नेल के लिए तैयारी:

 
char* buffer = st[0] + st[1] + st[2] + ....; 
int* metadata = new int[numberOfStrings * 2]; 
int lastpos = 0; 
for (int cnt = 0; cnt < 2* numberOfStrings; cnt+=2) 
{ 
    metadata[cnt] = lastpos; 
    lastpos += length(st[cnt]); 
    metadata[cnt] = length(st[cnt]); 
} 
कर्नेल में:
 
currentIndex = threadId + blockId * numberOfBlocks; 
char* currentString = buffer + metadata[2 * currentIndex]; 
int currentStringLength = metadata[2 * currentIndex + 1]; 

0

समस्या char ** पैरामीटर से जुड़ी प्रतीत होती है। इसे एक चार में बदलकर * चेतावनी हल हो गई, इसलिए मुझे संदेह है कि इस प्रकार के डेटा के साथ cuda में समस्या हो सकती है। शायद cuda पसंद करता है कि इस मामले में एक विशिष्ट cuda 2 डी arrays का उपयोग करता है।