एनवीआईडीआईए द्वारा पेश किए गए विशाल दस्तावेज पर ध्यान केंद्रित करने में कुछ समय व्यतीत करें।
प्रोग्रामिंग गाइड से:
float* devPtr;
cudaMalloc((void**)&devPtr, 256 * sizeof(*devPtr));
cudaMemset(devPtr, 0, 256 * sizeof(*devPtr));
कैसे स्मृति को आबंटित करने का एक सरल उदाहरण है कि। अब, अपने कर्नेल में, आप एक सूचक एक नाव के लिए इतना की तरह स्वीकार करना चाहिए:
__global__
void kernel1(float *some_neat_data)
{
some_neat_data[threadIdx.x]++;
}
__global__
void kernel2(float *potentially_that_same_neat_data)
{
potentially_that_same_neat_data[threadIdx.x] *= 0.3f;
}
तो अब आप उन्हें इतनी तरह आह्वान कर सकते हैं:
float* devPtr;
cudaMalloc((void**)&devPtr, 256 * sizeof(*devPtr));
cudaMemset(devPtr, 0, 256 * sizeof(*devPtr));
kernel1<<<1,128>>>(devPtr);
kernel2<<<1,128>>>(devPtr);
इस डेटा कई में प्रयोग किया जाता है के रूप में कार्य, मैं इसे वैश्विक होना चाहता हूं।
ग्लोबल्स का उपयोग करने के कुछ अच्छे कारण हैं। यह निश्चित रूप से एक नहीं है। मैं इस उदाहरण को विस्तारित करने के लिए एक अभ्यास के रूप में छोड़ दूंगा ताकि "devPtr" को वैश्विक दायरे में ले जाया जा सके।
संपादित करें:
ठीक है, बुनियादी समस्या यह है: अपने कर्नेल केवल कर सकते हैं पहुँच डिवाइस स्मृति और केवल वैश्विक-गुंजाइश संकेत दिए गए हैं कि वे उपयोग कर सकते हैं GPU होते हैं। अपने सीपीयू से कर्नेल को कॉल करते समय, दृश्यों के पीछे क्या होता है यह है कि कर्नेल निष्पादित होने से पहले पॉइंटर्स और प्राइमेटिव जीपीयू रजिस्टरों और/या साझा मेमोरी में कॉपी हो जाते हैं।
तो सबसे नज़दीकी मैं सुझाव दे सकता हूं: अपने लक्ष्यों को प्राप्त करने के लिए cudaMemcpyToSymbol() का उपयोग करें। लेकिन, पृष्ठभूमि में, मान लें कि एक अलग दृष्टिकोण सही बात हो सकती है।
#include <algorithm>
__constant__ float devPtr[1024];
__global__
void kernel1(float *some_neat_data)
{
some_neat_data[threadIdx.x] = devPtr[0] * devPtr[1];
}
__global__
void kernel2(float *potentially_that_same_neat_data)
{
potentially_that_same_neat_data[threadIdx.x] *= devPtr[2];
}
int main(int argc, char *argv[])
{
float some_data[256];
for (int i = 0; i < sizeof(some_data)/sizeof(some_data[0]); i++)
{
some_data[i] = i * 2;
}
cudaMemcpyToSymbol(devPtr, some_data, std::min(sizeof(some_data), sizeof(devPtr)));
float* otherDevPtr;
cudaMalloc((void**)&otherDevPtr, 256 * sizeof(*otherDevPtr));
cudaMemset(otherDevPtr, 0, 256 * sizeof(*otherDevPtr));
kernel1<<<1,128>>>(otherDevPtr);
kernel2<<<1,128>>>(otherDevPtr);
return 0;
}
इस उदाहरण के लिए '--ost-compilation = C++' को न भूलें।
साझा स्मृति का उपयोग करने पर भी एक नज़र डालें, वैश्विक डिवाइस मेमोरी परतों का सबसे धीमा है। – SpaceghostAli
आप कर्नेल को तर्क के रूप में डिवाइस पॉइंटर को पास करने के बजाय ग्लोबल्स का उपयोग क्यों करना चाहते हैं? ऐसा करने से आपको सीपीयू कोड में ग्लोबल मेमोरी का उपयोग करने के साथ ही सभी समान सीमाएं मिलती हैं। –