Akh*_*Akh 32 .net c# optimization .net-4.0
我正在使用Red Gate的Performance Profiler优化物理模拟程序.处理碰撞检测的代码的一部分有大约52个以下的小检查,在两个案例中处理3维26个方向的细胞.
CollisionPrimitiveList cell = innerGrid[cellIndex + 1];
if (cell.Count > 0)
contactsMade += collideWithCell(obj, cell, data, ref attemptedContacts);
cell = innerGrid[cellIndex + grid.XExtent];
if (cell.Count > 0)
contactsMade += collideWithCell(obj, cell, data, ref attemptedContacts);
cell = innerGrid[cellIndex + grid.XzLayerSize];
if (cell.Count > 0)
contactsMade += collideWithCell(obj, cell, data, ref attemptedContacts);
Run Code Online (Sandbox Code Playgroud)
作为程序的一个非常紧凑的循环,所有这些都必须采用相同的方法,但是我发现,在我将区域从两个维度扩展到三维之后(突然从16增加到52个检查),我突然发现,突然cell.Count不再被内联,即使它是一个简单的吸气剂.
public int Count { get { return count; } }
这引起了巨大的性能损失,我花了相当长的时间才发现,当cell.Count出现在方法中28次或更少时,它每次都被内联,但一旦cell.Count出现在方法中29次或更多次,它没有一次内联(即使绝大多数调用都来自很少执行的代码的最坏情况部分.)
回到我的问题,是否有人有任何想法绕过这个限制?我认为简单的解决方案只是使计数字段内部而非私密,但我想要一个比这更好的解决方案,或者至少只是更好地了解情况.我希望在http://msdn.microsoft.com/en-us/library/ms973858.aspx上的Microsoft编写高性能托管应用程序页面上会提到这类事情,但遗憾的是它不是(可能是因为它有多乱28个计数限制是?)
我使用的是.NET 4.0.
编辑:看起来我误解了我的小测试.我发现内联失败不是因为方法本身被调用了28次以上,而是因为它们应该被内联到的方法被一些标准"太长"了.这仍然让我感到困惑,因为我没有看到一个简单的getter如何理性地没有内联(并且我的分析器清楚地向我显示了内联的性能明显更好),但显然CLI JIT编译器拒绝内联任何内容只是因为这个方法已经很大了(稍微改变一下,我发现这个限制是1500的代码大小(来自idasm),超过这个限制就没有内联,即使在我的getter的情况下,一些测试显示没有额外的代码内联的开销).
谢谢.
我还没有对此进行测试,但似乎一种可能的解决方法是拥有多个返回相同内容的属性。可以想象,每个属性可以获得 28 个内联。
请注意,内联方法的次数很可能取决于该方法的本机代码的大小(请参阅http://blogs.msdn.com/b/vancem/archive/2008/08/19/to-inline- or-not-inline-that-is-the-question.aspx),数字 28 特定于该属性。简单的属性可能会比更复杂的方法内联更多次。