简单金属程序中的内存泄漏

夏瓦什克

我正在尝试学习 Metal 进行科学编程。我尝试创建一个简单的内核来进行形态膨胀。我面临的问题是,每次调用dilate图像时,内存似乎都会增加几 KB

我通过dilate在 for 循环中运行该方法 10000 次迭代来验证内存泄漏,并观察 Xcode 的调试导航器中分配的内存从 16MB 增长到 17MB。

您在我的代码中看到的任何内容会导致内存泄漏吗?我也将项目推送到Github以防万一。

class MorphologyIOS : public Morphology
{
public:
    MorphologyIOS(
        const uint kernel,
        const uint width,
        const uint height
    ) {
        device_ = MTLCreateSystemDefaultDevice();
        kernelSize_ = kernel;
        buffer_ = [device_ newBufferWithBytes:&kernelSize_ length:4 options:MTLStorageModeShared];
        library_ = [device_ newDefaultLibrary];
        commandQueue_ = [device_ newCommandQueue];
        identityFunction_ = [library_ newFunctionWithName:@"identity"];

        MTLTextureDescriptor* readDesc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormat::MTLPixelFormatR8Uint
            width:width height:height mipmapped:false];

        MTLTextureDescriptor* writeDesc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormat::MTLPixelFormatR8Uint
            width:width height:height mipmapped:false];

        [writeDesc setUsage:MTLTextureUsageShaderWrite];

        inTexture_ = [device_ newTextureWithDescriptor:readDesc];
        outTexture_ = [device_ newTextureWithDescriptor:writeDesc];

        entireImage_ = MTLRegionMake2D(0, 0, width, height);

        pipelineState_ = [device_ newComputePipelineStateWithFunction:identityFunction_ error:NULL];

    }

    virtual ~MorphologyIOS() override {}

    virtual std::shared_ptr<unsigned char> dilate(
        const std::shared_ptr<unsigned char>& inImage
    ) override {
        void* result = malloc(outTexture_.width * outTexture_.height);
        std::shared_ptr<unsigned char> outImage;
        @autoreleasepool
        {
            commandBuffer_ = [commandQueue_ commandBuffer];
            commandEncoder_ = [commandBuffer_ computeCommandEncoder];
            [commandEncoder_ setComputePipelineState:pipelineState_];

            [inTexture_ replaceRegion:entireImage_ mipmapLevel:0 withBytes:inImage.get() bytesPerRow:outTexture_.width];

            [commandEncoder_ setTexture:inTexture_ atIndex:0];
            [commandEncoder_ setTexture:outTexture_ atIndex:1];
            [commandEncoder_ setBuffer:buffer_ offset:0 atIndex:0];

            MTLSize threadGroupCount = MTLSizeMake(10, 10, 1);
            MTLSize threadGroups = MTLSizeMake(inTexture_.width / threadGroupCount.width,
                inTexture_.height / threadGroupCount.height, 1);

            [commandEncoder_ dispatchThreadgroups:threadGroups threadsPerThreadgroup:threadGroupCount];
            [commandEncoder_ endEncoding];
            [commandBuffer_ commit];
            [commandBuffer_ waitUntilCompleted];

            [outTexture_ getBytes:result bytesPerRow:outTexture_.width fromRegion:entireImage_ mipmapLevel:0];
            outImage.reset(reinterpret_cast<unsigned char*>(result));
        }

        return outImage;
    }
private:
    id<MTLDevice> device_;
    uint kernelSize_;
    id<MTLBuffer> buffer_;
    id<MTLLibrary> library_;
    id<MTLComputePipelineState> pipelineState_;
    id<MTLCommandQueue> commandQueue_;
    id<MTLFunction> identityFunction_;
    id<MTLCommandBuffer> commandBuffer_;
    id<MTLComputeCommandEncoder> commandEncoder_;
    id<MTLTexture> inTexture_;
    id<MTLTexture> outTexture_;
    MTLRegion entireImage_;
};

我的内核看起来像这样:

kernel void dilation(
    texture2d<uint, access::read> inTexture [[texture(0)]],
    texture2d<uint, access::write> outTexture [[texture(1)]],
    device uint *kernelSize [[buffer(0)]],
    uint2 gid [[thread_position_in_grid]]
) {
    uint halfKernel = kernelSize[0] / 2;
    uint minX = gid.x >= halfKernel ? gid.x - halfKernel : 0;
    uint minY = gid.y >= halfKernel ? gid.y - halfKernel : 0;
    uint maxX = gid.x + halfKernel < inTexture.get_width() ? gid.x + halfKernel : inTexture.get_width();
    uint maxY = gid.y + halfKernel < inTexture.get_height() ? gid.y + halfKernel : inTexture.get_height();
    uint maxValue = 0;
    for (uint i = minX; i <= maxX; i++)
    {
        for (uint j = minY; j <= maxY; j++)
        {
            uint4 value = inTexture.read(uint2(i, j));
            if (maxValue < value[0])
                maxValue = value[0];
        }
    }
    outTexture.write(maxValue, gid);
}
沃伦

这与其说是一个错误,不如说是捕获/验证层代表您进行一些簿记的产物。由于它不会在实际使用中发生,因此可能无需担心。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

mysqlcppconn程序中的内存泄漏

来自分类Dev

程序中的C内存泄漏

来自分类Dev

Haskell程序中的内存泄漏

来自分类Dev

非常简单的Android应用中的内存泄漏

来自分类Dev

简单查询导致Django中的内存泄漏

来自分类Dev

在一个非常简单的程序中检测到内存泄漏。该怎么办?

来自分类Dev

C程序中绝对丢失的内存泄漏

来自分类Dev

故意内存泄漏的程序?

来自分类Dev

在简单的Clojure程序中减少内存使用

来自分类Dev

了解Android应用程序中的内存泄漏

来自分类Dev

如何捕获Angular应用程序中的内存泄漏?

来自分类Dev

如何减少/消除Angular应用程序中的内存泄漏

来自分类Dev

Java Web应用程序中的内存泄漏

来自分类Dev

了解Android应用程序中的内存泄漏

来自分类Dev

让Valgrind从Python脚本调用的C ++程序中检测内存泄漏:

来自分类Dev

托管应用程序中的非托管内存泄漏

来自分类Dev

实时应用程序中的内存泄漏检查

来自分类Dev

如何跟踪Rails应用程序中的内存泄漏?

来自分类Dev

iPhone应用程序内存泄漏与NSMutableArray中的UIImages

来自分类Dev

如何减少/消除Angular应用程序中的内存泄漏

来自分类Dev

无法找出C应用程序中的内存泄漏

来自分类Dev

rxjs,节点,处理程序中的订阅内存泄漏

来自分类Dev

Scrapy中的内存泄漏

来自分类Dev

Golang中的内存泄漏

来自分类Dev

libcurl中的内存泄漏

来自分类Dev

MediaPlayer中的内存泄漏

来自分类Dev

QWebView中的内存泄漏

来自分类Dev

malloc中的内存泄漏?

来自分类Dev

C中的内存泄漏