سؤال

عندي حصة دراسية (انظر المثال عاليا) الذي يعمل كمجمع .NET لهيكل ذاكرة CUDA،
تخصيص باستخدام Cudamalloc () والإشارار باستخدام حقل عضو من النوع IntPtr.
(يستخدم الفصل DLLIMPORT من DLL DLL الأصلي الذي يلتف العديد من وظائف CUDA.)

يتحقق طرق التخلص من التخلص إذا كان المؤشر INTPTR.ZERO وإذا لم يدعو CudaFree ()
التي تخصها بنجاح الذاكرة (إرجاع نجاح CUDA)
ويضع المؤشر إلى intptr.zero.

تستدعي الطريقة النهائية طريقة التخلص منها.

المشكلة هو، أنه إذا تم استدعاء الأساليب النهائية دون استدعاء التخلص من ذلك،
ثم تعمل الدالة Cudafree () رمز خطأ "مؤشر الجهاز غير صالح".

راجعت وعنوان CudaFree () يتلقى هو نفس العنوان الذي تم إرجاعه بواسطة Cudamalloc () ولا يتم استدعاء أي من النمو () سابقا.

عندما أضيف استدعاء نداء للتخلص () يتم تحرير نفس العنوان بنجاح.

كان الحل الوحيد الذي وجدته هو عدم استدعاء طريقة التخلص من النهائي، ومع ذلك، قد يتسبب ذلك في تسرب الذاكرة، إذا تم استدعاء التخلص منها () دائما.

أي أفكار لماذا يحدث هذا؟ - واجهت نفس المشكلة مع CUDA 2.2 و 2.3، ضمن .NET 3.5 المزود بحزمة الخدمة SP1 على نظام التشغيل Windows Vista 64bit + GeForce 8800 وعلى نظام التشغيل Windows XP 32Pit + Quadro FX (غير متأكد من أي رقم).

Class CudaTity: IDEPOPOBLED {Private Intptr DataPointer؛ الحكمات العامة () {// يدعو cudamalloc () عبر dllimport، // يتلقى رمز الخطأ والطرق ينبض الانتصاف إذا لم يكن 0 // تعيين القيمة إلى this.dataPointer} public dispose () {en (this.datapointer! = intptr.zero) {// المكالمات cudafree () عبر dllimport، // يتلقى رمز الخطأ وإنهاء إيفاد الإنقراض إن لم يكن 0.dataPointer = intptr.zero؛ }} ~ cudaentity () {discose ()؛ }}
{// هذا الرمز يعمل var simentity = cudaentity جديد ()؛ Simentity.Dispose ()؛ }
{// هذا الرمز يسبب خطأ "مؤشر جهاز غير صالح" // خطأ في استدعاء النهوضية إلى Cudafree () Var Simentity = Cudaentity New ()؛ }
هل كانت مفيدة؟

المحلول

المشكلة هي أن النهضة النهائية تنفذ على موضوع GC، لا يمكن استخدام مورد CUDA المخصص في مؤشر ترابط واحد في مكان آخر. SNIP من دليل برمجة CUDA:

يمكن تنفيذ العديد من المواضيع المضيفة رمز الجهاز على نفس الجهاز، ولكن عن طريق التصميم، يمكن لموضوع مضيف تنفيذ رمز الجهاز على جهاز واحد فقط. ونتيجة لذلك، هناك حاجة مواضيع مضيف متعددة لتنفيذ رمز الجهاز على أجهزة متعددة. أيضا، لا يمكن استخدام أي موارد CUDA التي تم إنشاؤها من خلال وقت التشغيل في مؤشر ترابط مضيف واحد من خلال خيط مضيف آخر.

أفضل رهان الخاص بك هو استخدام using بيان، مما يضمن Dispose() يتم استدعاء الطريقة دائما في نهاية كتلة التعليمات البرمجية "المحمية":

using(CudaEntity ent = new CudaEntity())
{

}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top