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

标签 .net f# cuda garbage-collection

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

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

我是否有任何选择可以做到这一点,而不需要放弃 .NET 作为平台并为该语言编写自己的运行时?

最佳答案

我们通过将所有 CUDA 内存包装在托管包装类(在 C# 中,而不是在托管 C++ 中)并向其添加 SafeHandle 来实现此目的。这些类有自己的处置,但 SafeHandle 将负责真正的处置。顺便说一句,问题是,您使用的是驱动程序 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 有许多不同的纹理、数组、内存、倾斜内存、表面等句柄以及“销毁”方法,因此我们需要创建多个 SafeHandles。

数组的 SafeHandle 如下所示。

    /// <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 如下所示:

    /// <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;
            }
        }
    }

关于.net - 有没有办法让.NET GC管理Cuda内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48542766/

相关文章:

.net - 与 Remoting 相比,为什么 WCF 性能如此缓慢?

java - 访问同一类中另一个对象的私有(private)字段

c# - 连接未关闭。连接的当前状态是打开的。 C#错误

f# - 第三方类型的动态调度

CUDA 地址越界

c++ - 我的机器上 OpenCV 算法的 GPU 版本比 CPU 版本慢?

.net - .NET 事件的签名

C# 到 F# : Functional thinking vs. 多态性

f# - 4.5 版中的阴影

c++ - 如何使用模板正确定义函数