j'ai une classe (voir exemple ci-dessous) qui agit comme une enveloppe .NET pour une structure de mémoire CUDA,
alloué à l'aide cudaMalloc() et fait référence à l'aide d'un champ de membre de type IntPtr.
(La classe utilise DllImport d'une DLL C native qui enveloppe diverses fonctionnalités de CUDA.)
Les méthodes Dispose vérifie si le pointeur est IntPtr.Zero et si pas les appels cudaFree()
qui désalloue avec succès la mémoire (retours Succès CUDA)
et définit le pointeur sur IntPtr.Zero.
La méthode finalize appelle la méthode dispose.
Le problème est que, si les méthodes Finalize est appelé avec le disposer appelé précédemment,
alors la fonction cudaFree() définit un code d'erreur de « pointeur de périphérique non valide ».
J'ai vérifié et l'adresse que cudaFree() reçoit est la même adresse retournée par le cudaMalloc() et aucune disposition() n'a été appelée précédemment. Lorsque j'ajoute un appel explict à disposer(), la même adresse est libérée avec succès.
La seule solution de contournement que j'ai trouvée était de ne pas appeler la méthode de disposition du finaliseur, cependant, cela pourrait causer une fuite de mémoire, si la méthode dispose() n'est pas toujours appelée.
Des idées pour lesquelles cela se produit? - J'ai rencontré le même problème avec CUDA 2.2 et 2.3, sous .NET 3.5 SP1 sur Windows Vista 64bit + GeForce 8800 et sur Windows XP 32bit + Quadro FX (je ne sais pas quel numéro).
CUDA problèmes mondiaux de désallocation de mémoire dans .NET
class CudaEntity : IDisposable { private IntPtr dataPointer; public CudaEntity() { // Calls cudaMalloc() via DllImport, // receives error code and throws expection if not 0 // assigns value to this.dataPointer } public Dispose() { if (this.dataPointer != IntPtr.Zero) { // Calls cudaFree() via DllImport, // receives error code and throws expection if not 0 this.dataPointer = IntPtr.Zero; } } ~CudaEntity() { Dispose(); } }
{ // this code works var myEntity = new CudaEntity(); myEntity.Dispose(); }
{ // This code cause a "invalid device pointer" // error on finalizer's call to cudaFree() var myEntity = new CudaEntity(); }
Je ne jette une exception si le gratuit a échoué. Les lignes directrices sur la SP suggèrent d'éviter cela. – TrueWill
J'ai seulement ajouté que pour aider au débogage du problème, cependant, pour une raison inconnue sur l'un des 2 PC que j'ai travaillé sur VS traite automatiquement le code retour comme une exception sans que j'en lève un! –