2012-12-21 12 views
7

मुझे पता है कि "प्रत्येक वार में निरंतर धागे होते हैं, थ्रेड 0 युक्त पहले वार्प के साथ थ्रेड आईडी बढ़ते हैं" तो पहले 32 थ्रेड पहले वार में होना चाहिए। साथ ही मुझे पता है कि एक वार में सभी धागे किसी भी उपलब्ध स्ट्रीमिंग मल्टीप्रोसेसर पर एक साथ निष्पादित किए जाते हैं।CUDA। पहले 32 धागे को अनलोल कैसे करें ताकि उन्हें समानांतर में निष्पादित किया जा सके?

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

#define BLOCK_SIZE 128 

__global__ void reduce (int * inData, int * outData) 
{ 
__shared__ int data [BLOCK_SIZE]; 
int tid = threadIdx.x; 
int i = blockIdx.x * blockDim.x + threadIdx.x; 

data [tid] = inData [i] + inData [i + blockDim.x/2 ]; 
__syncthreads(); 

for (int s = blockDim.x/4; s > 32; s >>= 1) 
{ 
    if (tid < s) 
    data [tid] += data [tid + s]; 
    __syncthreads(); 
} 

if (tid < 32) 
{ 
    data [tid] += data [tid + 32]; 
    __syncthreads(); 
    data [tid] += data [tid + 16]; 
    __syncthreads(); 
    data [tid] += data [tid + 8]; 
    __syncthreads(); 
    data [tid] += data [tid + 4]; 
    __syncthreads(); 
    data [tid] += data [tid + 2]; 
    __syncthreads(); 
    data [tid] += data [tid + 1]; 
    __syncthreads(); 
} 
if (tid == 0) 
    outData [blockIdx.x] = data [0]; 
} 

void main() 
{ 
... 
reduce<<<dim3(128), dim3(128)>>>(dev_data, dev_res); 
... 
} 

पीएस मैं GT560Ti

उत्तर

7

उपयोग कर रहा हूँ आप अस्थिर रूप में साझा स्मृति चर घोषित करना चाहिए:

__shared__ volatile int data [BLOCK_SIZE]; 

समस्या आप देख रहे हैं फर्मी वास्तुकला और संकलक अनुकूलन के एक विरूपण साक्ष्य है। फर्मि आर्किटेक्चर में साझा स्मृति पर सीधे संचालन करने के निर्देशों की कमी है (वे जी 80/9 0/जीटी 200 श्रृंखला में मौजूद थे)। इसलिए सबकुछ पंजीकृत, मैनिप्लेटेड, और साझा मेमोरी में संग्रहीत करने के लिए लोड किया जाता है। लेकिन संकलक यह समझने के लिए स्वतंत्र है कि उस कोड को तेजी से बनाया जा सकता है यदि पंजीकरण में संचालन की श्रृंखला का संचालन किया गया हो, इंटरमीडिएट लोड और स्टोर से साझा स्मृति तक। यह को को छोड़कर पूरी तरह से ठीक है जब आप उसी तरह के कमांड कोड के रूप में थ्रेड के अंतर्निहित सिंक्रनाइज़ेशन पर निर्भर हैं, जैसे कि इस तरह के कमी कोड में।

साझा मेमोरी बफर को अस्थिर के रूप में घोषित करके, आप संकुचन को प्रत्येक चरण के बाद साझा स्मृति लेखन को लागू करने के लिए मजबूर कर रहे हैं, और वार्प के भीतर धागे के बीच अंतर्निहित डेटा सिंक्रनाइज़ेशन बहाल कर दिया गया है।

इस मुद्दे पर फर्मि के लिए प्रोग्रामिंग नोट्स पर चर्चा की गई है जो CUDA टूलकिट के साथ जहाज (या शायद भेज दिया गया) है।

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

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