मैं विभिन्न ब्लॉकों में अंतिम योग की परमाणु गणना के साथ डबल परिशुद्धता सरणी के लिए क्लासिक डॉट-उत्पाद कर्नेल को कार्यान्वित करने का प्रयास कर रहा हूं। मैंने प्रोग्रामिंग गाइड के पेज 116 में बताए गए डबल परिशुद्धता के लिए परमाणु का उपयोग किया। संभवतः मैं कुछ गलत कर रहा हूं। प्रत्येक ब्लॉक में धागे के आंशिक रकम सही ढंग से गणना की जाती हैं लेकिन बाद में परमाणु ऑपरेशन ठीक से काम नहीं कर रहा है चूंकि हर बार जब मैं एक ही डेटा के साथ अपना कर्नेल चलाता हूं, तो मुझे अलग-अलग परिणाम मिलते हैं। अगर कोई गलती तलाश सकता है या वैकल्पिक समाधान प्रदान कर सकता है तो मैं आभारी रहूंगा! यहाँसीयूडीए डॉट उत्पाद
__global__ void cuda_dot_kernel(int *n,double *a, double *b, double *dot_res)
{
__shared__ double cache[threadsPerBlock]; //thread shared memory
int global_tid=threadIdx.x + blockIdx.x * blockDim.x;
int i=0,cacheIndex=0;
double temp = 0;
cacheIndex = threadIdx.x;
while (global_tid < (*n)) {
temp += a[global_tid] * b[global_tid];
global_tid += blockDim.x * gridDim.x;
}
cache[cacheIndex] = temp;
__syncthreads();
for (i=blockDim.x/2; i>0; i>>=1) {
if (threadIdx.x < i) {
cache[threadIdx.x] += cache[threadIdx.x + i];
}
__syncthreads();
}
__syncthreads();
if (cacheIndex==0) {
*dot_res=cuda_atomicAdd(dot_res,cache[0]);
}
}
और मेरे डिवाइस समारोह atomicAdd है: यहाँ मेरी गिरी है
__device__ double cuda_atomicAdd(double *address, double val)
{
double assumed,old=*address;
do {
assumed=old;
old= __longlong_as_double(atomicCAS((unsigned long long int*)address,
__double_as_longlong(assumed),
__double_as_longlong(val+assumed)));
}while (assumed!=old);
return old;
}
साझा स्मृति परमाणु बहुत धीमी हैं। यह एक डॉट उत्पाद को लागू करने का एक अच्छा तरीका नहीं है। जेरेड पॉइंट आउट के रूप में, आप थ्रस्ट का उपयोग करने से बेहतर हैं। यदि आप अपना कोड लिखने का आग्रह करते हैं, और आप वास्तव में इसे एक कर्नेल में करना चाहते हैं, तो CUDA SDK कोड नमूने में थ्रेडफेंस रेडक्शन नमूना देखें। यह बहुत अधिक कुशल होना चाहिए (यह एक डॉट उत्पाद नहीं है, केवल एक योग कमी है, लेकिन प्रारंभिक तत्व-वार गुणा जोड़ना छोटा होना चाहिए।) – harrism
@harrism: इस कोड में साझा स्मृति परमाणु कहां हैं? यह अवरुद्ध आंशिक कम मूल्यों के सारांश को पूरा करने के लिए वैश्विक स्मृति परमाणु संचालन के साथ एक मानक साझा स्मृति कमी है। – talonmies
क्षमा करें, मैंने अपने सिर पर परमाणु तर्कों को स्थानांतरित किया! भले ही, आप थ्रेडफेंस का उपयोग करते समय एक कर्नेल में कमी को लागू करने के लिए परमाणुओं की आवश्यकता नहीं होनी चाहिए। – harrism