。NET Core中如何分配连续和固定内存

问题描述 投票:2回答:1

我正在一个物理仿真项目中,性能至关重要,我认为内存管理是一个瓶颈。目前,我有包含固定数量的刚体,粒子和力的缓冲对象。在开始模拟之前,所有物理实体都在其缓冲区中初始化。当需要一个实体时,选择第一个不活动的实体,否则选择最旧的实体,并且当不再需要它时,将其移到末尾,因此所有活动实体都被放在前面。

这是我正在使用的数据结构。

public sealed class Buffer<TValue> : IEnumerable<BufferElement<TValue>> where TValue : new()
{
    public Buffer(int capacity)
    {
        Count = 0;
        Capacity = capacity;
        Elements = new BufferElement<TValue>[capacity];

        for (var index = 0; index < Elements.Length; index++)
        {
            Elements[index] = new BufferElement<TValue>();
        }
    }

    public int Count { get; private set; }

    public int Capacity { get; private set; }

    private int ActiveCount { get; set; }

    private BufferElement<TValue>[] Elements { get; }

    public BufferElement<TValue> Activate()
    {
        if (Count == ActiveCount) Count = 0;

        var bufferElement = Elements[Count++];

        if (!bufferElement.Active)
        {
            bufferElement.Active = true;
            ActiveCount++;
        }

        return bufferElement;
    }

    public void Deactivate(BufferElement element)
    {
        if (!element.Active) return;

        element.Active = false;

        var lhs = element.Index;
        var rhs = --ActiveCount;

        Elements[lhs] = Elements[rhs];
        Elements[rhs] = element;

        Elements[lhs].Index = lhs;
        Elements[rhs].Index = rhs;
    }
}

阅读了.NET Core如何处理数组后,可能有两件事。第一种是每次访问数组中的元素时,它都会执行安全检查,第二种是GC可以将数组复制到新的内存地址。

我希望所有包含物理实体的缓冲区不进行任何安全检查,并尽可能固定在连续内存中。我相信这应该是可能的,因为每个缓冲区的大小都是固定的,并且元素(刚体,粒子,力)的大小也都是固定的。

[C#中似乎有很多管理内存的方法,而且我很难确定在这种情况下哪种方法对我合适。

现在,问题归结为三个部分:

  1. 可以这样做吗?
  2. 如果是这样,管理内存的最佳方法是什么?
  3. 而且,正确的实现会是什么样?
c# memory-management .net-core
1个回答
1
投票

首先,是的,可以做到。第二,best确实取决于,因为存在许多折衷,并且这很快成为opinionated帖子。第三,最简便的选择是使用fixed关键字在unsafe上下文中分配数组(此处没有对数组进行安全检查,也不允许您使用C样式的指针)并固定其地址,以便它不会尽管使用SpanMemory可能会更容易,但是如果正确使用fixedunsafe的低级方法可以产生更好的性能。看看this,它是官方文档,上面有完整的示例。最后一个技巧是尝试切换到struct而不是如果可能,它们没有内存开销,并且具有更高的内存密度,从而产生了更好的缓存访问时间,因为还有更多的缓存可以使用。

© www.soinside.com 2019 - 2024. All rights reserved.