c# - C#中的内存布局优化

标签 c# performance memory optimization jit

免责声明:下面的措辞中可能存在一些误解,如果我误解了我的代码在 C# 中处理的方式,从我写到它看起来像零和一的那一刻,请纠正我

问题如下(已链接):

在 C# 中,我的数据结构和/或我的数据操作实现是否会对性能产生影响,无论我是否使用优化技术?

编译器在输出IL的时候做了什么,可靠吗? 含义:如果我让我的数据 SOA 会是 IL 中的 SOA 吗?总是?

当 JIT 读取 IL 时,我的数据结构会发生什么变化?它改变了吗?它会自动优化以适合我的处理器吗?

cf: that talk about C/C++

我知道这个演讲是针对原生代码的,并讨论处理器布局的细节与原生代码中的数据布局。

我也知道 C# 编译器和 JIT 编译器会针对这些问题为我优化。

基本上我想知道这些优化是否会对我的性能产生影响:

  • SOA 代替 AOS
  • 向量访问模式(在内存中连续访问)
  • 等等......你的名字......

我从事游戏开发工作,性能至关重要,我们处理大量数据,我们需要每秒至少执行 24 次,我不能让 GC 做 300 毫秒的事情,也不能让内存在整个过程中被访问/分配当我试图检测 3000 个不同对象之间的碰撞时的位置

关于我阅读但没有真正回答问题的内容的引用:

但是这些并没有回答与处理器和数据布局实现相关的性能成本。


在汉斯回答之后更进一步:

当你说:“你可以追求 SOA,但这无济于事。是的,你的程序会因为所有结构复制而变慢,并且以一种确定性的方式这样做。但这并不能阻止雨。你得到最坏的结果,一个缓慢的程序和完全相同的停顿。”

这并不意味着我的程序不会从 SOA 中受益,它会更快(可能),因为它有助于处理我的数据。只是它不会对 GC 本身产生影响。

另一件事是,如果我不对我的数据布局进行 SOA 或其他改进,编译器不会为我改进,对吧?我不能依赖编译器来处理那种事情?

最佳答案

担心GC就像担心今天会不会下雨一样。迟早要下雨,你无法阻止它。这是必需的,如果不这样做,你就无法保持草坪看起来很绿。你永远不想做的是故意阻止它下雨。因为如果你这样做,它会像洪水一样倾泻而下,把那漂亮的草坪洒掉。你想要的是稳定的毛毛雨。最好是在你不看的晚上。

.NET GC 强烈支持这一点。只有小的 gen #0 和 #1 集合会暂停你的程序。当您的代码继续执行时,昂贵的 gen#2 集合在后台发生。最坏情况下的暂停徘徊在接近一百微秒的地方。这与您的程序将在现代操作系统上暂停的其他原因非常难以区分。就像您的游戏循环因需要运行另一个更高优先级的内核线程而暂时暂停一样。只是毛毛雨,肉眼无法观察到。

您可以追求 SOA,但这无济于事。是的,你的程序会因为所有的结构复制而变慢,并且以一种确定性的方式这样做。但这并不能阻止雨。你得到了两者中最糟糕的,一个缓慢的程序完全相同的停顿。

不用担心下雨,只要确保在正确的时间下雨即可。要利用后台 GC,您需要对数据进行结构化,使其生命周期非常短,因此它很容易在 gen #0/1 集合中消失。或者生活很长时间,所以它在第 2 代找到了一个舒适的家并在那里呆了一段时间。这通常是程序中非常常见的模式,尤其是在游戏中。您几乎不需要做任何事情。

关于c# - C#中的内存布局优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29192679/

相关文章:

c# - 如何使用.NET XML序列化将对象序列化为单个值

c# - 如何在接收器事件中心编辑 EvenData 消息?

c# - SlimDX 创建常量缓冲区导致无效参数异常

c - 是否可以通过少于 9 次比较来检查 2 组 3 个整数中的任何一个是否相等?

css - 指定 element.class { ... } 与仅指定 .class { ... } 的性能提升?

c - 如何立即调入新分配的虚拟内存

c# - .NET 4.0 中的重大变化

javascript - 在客户端的浏览器中解压缩内容

c++ - 将整型数组作为另一个不相关整型类型的数组进行访问的安全且符合标准的方法?

c - 内存地址如何知道数组的长度?