gpt4 book ai didi

c# - 如何在 .NET Core 中分配连续和固定内存

转载 作者:太空宇宙 更新时间:2023-11-03 11:58:10 33 4
gpt4 key购买 nike

我正在从事一个性能至关重要的物理模拟项目,我认为瓶颈是我的内存管理。目前,我有包含固定数量的刚体、粒子和力的缓冲对象。在模拟开始之前,所有物理实体都在其缓冲区内初始化。当需要一个实体时,选择第一个不活跃的,否则,最旧的,当不再需要时,将它移到最后,所以活跃的实体都是前面打包的。

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

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. 而且,正确的实现应该是什么样的?

最佳答案

首先,是的,这是可以做到的。其次,最好的真的取决于,因为存在许多权衡,这很快就变成了一个自以为是的帖子。第三,最简单的替代方法是使用 fixed 关键字在 unsafe 上下文中分配数组(此处不对数组进行安全检查,并允许您使用 C 样式指针)并固定它的地址,这样它就不会改变,尽管使用 SpanMemory 可能更容易,fixed 的低级方法如果使用得当,unsafe 可以产生更好的性能。查看this ,这是官方文档,里面有很多简洁的例子。最后一个提示,尝试切换到 struct 而不是如果可能,它们没有内存开销和更高的内存密度,产生更好的缓存访问时间,因为更多的将适合在缓存中。

关于c# - 如何在 .NET Core 中分配连续和固定内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58566158/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com