有没有办法让.NET GC管理Cuda内存?
我正在研究编译成F#和Cuda的文件。虽然我对.NET对象的内存管理没有问题,但Cuda内存属于非托管部分,需要手动处理 我现在对这种语言唯一真正遗憾的是,当前词汇范围内的内存管理方式使为其编写ML库变得更加复杂。它将代码耦合到一个不舒服的程度,并迫使我对代码库进行CPS,以便对其进行处理。我现在使用的这种基于区域的内存管理只是部分解决方案,如果GC可以处理分配的某些部分,我更喜欢它有没有办法让.NET GC管理Cuda内存?,.net,f#,cuda,garbage-collection,.net,F#,Cuda,Garbage Collection,我正在研究编译成F#和Cuda的文件。虽然我对.NET对象的内存管理没有问题,但Cuda内存属于非托管部分,需要手动处理 我现在对这种语言唯一真正遗憾的是,当前词汇范围内的内存管理方式使为其编写ML库变得更加复杂。它将代码耦合到一个不舒服的程度,并迫使我对代码库进行CPS,以便对其进行处理。我现在使用的这种基于区域的内存管理只是部分解决方案,如果GC可以处理分配的某些部分,我更喜欢它 我有没有选择不用放弃.NET作为平台并为该语言编写自己的运行时来实现这一点?我们通过将所有CUDA内存包装在托管
我有没有选择不用放弃.NET作为平台并为该语言编写自己的运行时来实现这一点?我们通过将所有CUDA内存包装在托管包装类中(在C#中,而不是在托管C++中)并添加安全句柄来实现这一点。这些类有自己的dispose,但SafeHandle将负责实际的dispose。顺便问一下,问题是,您是使用驱动程序API还是运行时API。因为下面的例子会有些不同 给你一个线索:
/// <summary>
/// Abstract base class for all CUDA memories (linear, pitched, array, surface).
/// </summary>
public abstract class CudaMemory : CudaDeviceObject, ICudaMemory
{
#region IArray
/// <summary>
/// Dimension of Array
/// </summary>
int[] IArray.Dim
{
get { return new[] { Width, Height, Depth }; }
}
#endregion
#region ICudaMemory
/// <summary>
/// Returns the memory type.
/// </summary>
public abstract CudaMemoryType MemoryType
{
get;
}
#endregion
#region CudaDeviceObject
/// <summary>
/// Holds the pointer to the safe handle
/// </summary>
protected internal CudaSafeHandle myDevicePtr;
/// <summary>
/// Holds the device pointer to the device memory.
/// </summary>
public override SafeHandle Handle => myDevicePtr;
.
.
.
//
///所有CUDA内存(线性、倾斜、阵列、曲面)的抽象基类。
///
公共抽象类CudaMemory:cudadevieceobject,ICudaMemory
{
#区域射线
///
///数组维数
///
int[]IArray.Dim
{
获取{returnnew[]{Width,Height,Depth};}
}
#端区
#区域性乳腺癌
///
///返回内存类型。
///
公共抽象CudaMemoryType MemoryType
{
得到;
}
#端区
#区域CudaDeviceObject
///
///保持指向安全句柄的指针
///
受保护的内部CudaSafeHandle myDevicePtr;
///
///保存指向设备内存的设备指针。
///
公共覆盖安全句柄=>myDevicePtr;
.
.
.
由于CUDA有许多不同的纹理、数组、内存、倾斜内存、曲面等句柄,以及“销毁”方法,我们需要创建几个安全句柄
数组的安全句柄如下所示
/// <summary>
/// SafeHandle to control the lifetime of the Cuda context.
/// </summary>
public sealed class CudaSafeArrayHandle : CudaSafeHandle
{
public CudaSafeArrayHandle() : base( true )
{
}
protected override bool ReleaseHandle()
{
try
{
CUDA.Assert(CUDADriverAPI.cuArrayDestroy(DangerousGetHandle()));
return true;
}
catch
{
return false;
}
}
}
//
///SafeHandle用于控制Cuda上下文的生存期。
///
公共密封类CudaSafeArrayHandle:CudaSafeHandle
{
public-CudaSafeArrayHandle():base(true)
{
}
受保护的覆盖布尔释放句柄()
{
尝试
{
Assert(CUDADriverAPI.cuArrayDestroy(DangerousGetHandle());
返回true;
}
抓住
{
返回false;
}
}
}
倾斜内存的安全手柄如下所示:
/// <summary>
/// SafeHandle to control the lifetime of the Cuda context.
/// </summary>
public class CudaSafeDevicePtrLinearMemoryHandle : CudaSafeDevicePtrHandle
{
public CudaSafeDevicePtrLinearMemoryHandle() : base(true)
{
}
protected override bool ReleaseHandle()
{
try
{
CUDA.Assert(CUDADriverAPI.cuMemFree(DangerousGetHandle()));
return true;
}
catch
{
return false;
}
}
}
//
///SafeHandle用于控制Cuda上下文的生存期。
///
公共类CudaSafeDevicePtrLinearMemoryHandle:CudaSafeDevicePtrHandle
{
公共CudaSafeDevicePtrLinearMemoryHandle():base(true)
{
}
受保护的覆盖布尔释放句柄()
{
尝试
{
Assert(CUDADriverAPI.cuMemFree(DangerousGetHandle());
返回true;
}
抓住
{
返回false;
}
}
}
这很有趣。如果你不介意的话,我想看看CudaSafeHandle
和CudaSafeDevicePtrHandle
是如何实现的。我的目标是继承SafeHandle
并实现我自己需要的句柄吗?另外,如果你的库是开源的,我不介意链接到它。这两个类都是抽象的我只是简单地把它们放进去,因为我想稍后注入一些跟踪。所以处理程序抛出一个NotImplementedException。这个库的问题是它是由我们公司提供的,所以我只能给你一些指导、提示和代码片段。我注意到,对于网络上的许多示例,ReleaseHandle
方法具有[可靠性合同(Consistency.WillNotCorruptState,Cer.Success)]
attribute。如果我忘记添加它会有问题吗?事实上我不知道。从文档中可以看出,这是方法/类的作者和用户之间的某种契约。但是我不知道运行时如何处理此属性。