में डिवाइस मेमोरी आवंटन लपेटना मैं इस समय CUDA का उपयोग करना शुरू कर रहा हूं और मुझे यह स्वीकार करना होगा कि मैं सी एपीआई से थोड़ा निराश हूं। मैं सी चुनने के कारणों को समझता हूं लेकिन भाषा सी ++ पर आधारित थी, कई पहलुओं को बहुत आसान बना दिया गया था, उदाहरण के लिए डिवाइस मेमोरी आवंटन (cudaMalloc
के माध्यम से)।CUDA: C++
मेरी योजना प्लेसमेंट new
और आरएआईआई (दो विकल्प) के साथ अधिभारित operator new
का उपयोग करके स्वयं को करना था। मैं सोच रहा हूं कि क्या ऐसी कोई चेतावनी है जो मैंने अभी तक नहीं देखी है। कोड काम करने के लिए लगता है लेकिन मैं अभी भी संभावित मेमोरी लीक के बारे में सोच रहा हूं।
आरए II कोड के उपयोग के रूप में निम्नानुसार होगा:
CudaArray<float> device_data(SIZE);
// Use `device_data` as if it were a raw pointer.
शायद एक वर्ग इस संदर्भ में overkill है (खासकर जब से तुम अब भी cudaMemcpy
उपयोग करने के लिए होगा, वर्ग केवल आरए II encapsulating) इसलिए अन्य दृष्टिकोण नियुक्ति new
होगा:
float* device_data = new (cudaDevice) float[SIZE];
// Use `device_data` …
operator delete [](device_data, cudaDevice);
यहाँ, cudaDevice
केवल करने के लिए एक टैग के रूप में कार्य करता है अधिभार ट्रिगर करें। हालांकि, सामान्य प्लेसमेंट new
में यह प्लेसमेंट इंगित करेगा, मुझे सिंटैक्स अजीब रूप से सुसंगत और शायद कक्षा का उपयोग करने के लिए भी बेहतर लगता है।
मैं हर तरह की आलोचना की सराहना करता हूं। क्या किसी को शायद पता चलेगा कि इस दिशा में कुछ सीयूडीए के अगले संस्करण के लिए योजनाबद्ध है (जैसा कि मैंने सुना है, उसके सी ++ समर्थन में सुधार करेगा, जो भी इसका मतलब है)।
तो, मेरे सवाल का वास्तव में तीन गुना है:
- अपना स्थान
new
अधिभार शब्दार्थ सही है? क्या यह स्मृति रिसाव करता है? - क्या किसी के पास भविष्य में सीयूडीए विकास के बारे में जानकारी है जो इस सामान्य दिशा में जाती है (चलिए इसका सामना करते हैं: सी ++ एस * सीके में सी इंटरफेस)?
- मैं इसे लगातार तरीके से कैसे ले सकता हूं (विचार करने के लिए अन्य एपीआई हैं, उदाहरण के लिए न केवल डिवाइस मेमोरी बल्कि एक स्थिर मेमोरी स्टोर और बनावट मेमोरी भी है)?
// Singleton tag for CUDA device memory placement.
struct CudaDevice {
static CudaDevice const& get() { return instance; }
private:
static CudaDevice const instance;
CudaDevice() { }
CudaDevice(CudaDevice const&);
CudaDevice& operator =(CudaDevice const&);
} const& cudaDevice = CudaDevice::get();
CudaDevice const CudaDevice::instance;
inline void* operator new [](std::size_t nbytes, CudaDevice const&) {
void* ret;
cudaMalloc(&ret, nbytes);
return ret;
}
inline void operator delete [](void* p, CudaDevice const&) throw() {
cudaFree(p);
}
template <typename T>
class CudaArray {
public:
explicit
CudaArray(std::size_t size) : size(size), data(new (cudaDevice) T[size]) { }
operator T*() { return data; }
~CudaArray() {
operator delete [](data, cudaDevice);
}
private:
std::size_t const size;
T* const data;
CudaArray(CudaArray const&);
CudaArray& operator =(CudaArray const&);
};
यहां कार्यरत सिंगलटन के बारे में: हाँ, मैं अपनी कमियां के बारे में पता कर रहा हूँ। हालांकि, ये इस संदर्भ में प्रासंगिक नहीं हैं। मुझे बस एक छोटा प्रकार का टैग था जो कॉपी करने योग्य नहीं था। बाकी सब कुछ (यानी बहुप्रचार विचार, प्रारंभिक समय) लागू नहीं होता है।
सिंगलटन का आपका कार्यान्वयन सबसे खतरनाक है। सी ++ में सिंगलटन बनाने के तरीके के बारे में कई अन्य चर्चाएं देखें। –
हाँ, आप सही हैं। हालांकि, कोड के नीचे मेरा नया स्पष्टीकरण देखें। –