【发布时间】:2015-05-25 09:44:31
【问题描述】:
免责声明:下面的措辞中可能存在一些误解,如果我误解了我的代码在 C# 中处理的方式,从我写到它看起来像零和一的那一刻,请纠正我
问题如下(已链接):
在 C# 中,我的数据结构和/或我的数据操作实现是否会对性能产生影响,无论我是否使用优化技术?
编译器在输出IL的时候做了什么,可靠吗? 含义:如果我让我的数据 SOA 会是 IL 中的 SOA 吗?总是?
当 JIT 读取 IL 时,我的数据结构会发生什么变化?它改变了吗?它会自动优化以适合我的处理器吗?
我知道这个演讲是针对原生代码的,并且会讨论处理器布局的细节与原生代码中的数据布局。
我也知道 C# 编译器和 JIT 编译器会针对这些问题为我优化。
基本上我想知道这些优化是否会对我的性能产生影响:
- SOA 代替 AOS
- 向量访问模式(在内存中连续访问)
- 等等...你的名字...
我从事游戏开发工作,性能至关重要,我们处理大量数据,我们需要每秒至少执行 24 次,我不能让 GC 做 300 毫秒的事情,也不能让内存在整个过程中被访问/分配当我试图检测 3000 个不同对象之间的碰撞时的位置
关于我阅读但没有真正回答问题的内容的参考:
Excellent Eric Lippert article about structs and values types in C#(如果您认为值类型总是在 C# 的堆栈中,请阅读它)
Excellent video about PerfView to track your GC behaviour and it's impact on your perfs
That SO question about Best practices to optimize memory in C#(更重要的是答案)
但这些并没有回答与处理器和数据布局实现相关的性能成本。
在汉斯回答之后更进一步:
当你说:“你可以追求 SOA,但这无济于事。是的,你的程序会因为所有结构复制而变慢,并且以一种确定性的方式这样做。但这并不能阻止雨。你得到最坏的结果,一个缓慢的程序和完全相同的停顿。”
这并不意味着我的程序不会从 SOA 中受益,它会更快(可能),因为它有助于处理我的数据。只是它不会对 GC 本身产生影响。
另一件事是,如果我不对我的数据布局进行 SOA 或其他改进,编译器不会为我改进,对吗?我不能依赖编译器来处理那种事情?
【问题讨论】:
-
如果你在谈论这个级别的东西,C#(或任何托管内存环境)可能不适合你。但话又说回来......你是在实时计算、金融计算、大数据等领域工作吗?
-
实时,但可以正确使用 C# 来提供我希望的那种级别的控制
-
布局没有根本改变。
-
@GéryArduino 根据定义,Real time 和 Garbage Collector 是互斥的。
-
@Aron 您可以在 C# 中使用一些编程技术,例如对象池/预分配以避免分配(称为 zero alloc / gen zero 在行话中)。甚至还有plugins helping you with this。诚然,这不再是惯用的 C#,它很难正确,它需要广泛的分析,但它肯定是可能的。
标签: c# performance memory optimization jit