Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有办法让.NET GC管理Cuda内存?_.net_F#_Cuda_Garbage Collection - Fatal编程技术网

有没有办法让.NET GC管理Cuda内存?

有没有办法让.NET GC管理Cuda内存?,.net,f#,cuda,garbage-collection,.net,F#,Cuda,Garbage Collection,我正在研究编译成F#和Cuda的文件。虽然我对.NET对象的内存管理没有问题,但Cuda内存属于非托管部分,需要手动处理 我现在对这种语言唯一真正遗憾的是,当前词汇范围内的内存管理方式使为其编写ML库变得更加复杂。它将代码耦合到一个不舒服的程度,并迫使我对代码库进行CPS,以便对其进行处理。我现在使用的这种基于区域的内存管理只是部分解决方案,如果GC可以处理分配的某些部分,我更喜欢它 我有没有选择不用放弃.NET作为平台并为该语言编写自己的运行时来实现这一点?我们通过将所有CUDA内存包装在托管

我正在研究编译成F#和Cuda的文件。虽然我对.NET对象的内存管理没有问题,但Cuda内存属于非托管部分,需要手动处理

我现在对这种语言唯一真正遗憾的是,当前词汇范围内的内存管理方式使为其编写ML库变得更加复杂。它将代码耦合到一个不舒服的程度,并迫使我对代码库进行CPS,以便对其进行处理。我现在使用的这种基于区域的内存管理只是部分解决方案,如果GC可以处理分配的某些部分,我更喜欢它


我有没有选择不用放弃.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。如果我忘记添加它会有问题吗?事实上我不知道。从文档中可以看出,这是方法/类的作者和用户之间的某种契约。但是我不知道运行时如何处理此属性。