3

下面的文章讨论了另一种堆结构,该结构考虑到大多数服务器都是虚拟化的,因此大部分内存被分页到磁盘。

http://queue.acm.org/detail.cfm?id=1814327

.NET 开发人员能否(或应该)实现 B 堆数据结构,以便在同一个虚拟内存页面中维护父子关系?这将如何或在哪里实施?

澄清
换句话说,.NET 中是否需要这种类型的数据结构作为原始类型?确实,它应该在 CLR 或 ap/invoke 中本地实现。

当服务器管理员在虚拟机中部署我的 .NET 应用程序时,这种二进制堆优化是否有意义?如果是这样,什么时候有意义?(对象数量等)

4

2 回答 2

1

至少在一定程度上,BCL 集合似乎确实考虑了分页问题。它们还考虑了 CPU 缓存问题(在某些方面重叠,因为内存的位置会影响两者,尽管方式不同)。

考虑到Queue<T>使用数组进行内部存储。在纯粹的随机访问术语中(也就是说,分页或 CPU 缓存刷新永远不会产生任何成本),这是一个糟糕的选择;队列几乎总是在一个点单独添加并从另一个点删除,因此作为单链表的内部实现几乎会在所有方面获胜(就此而言,就遍历队列而言 - 它也支持- 在纯随机访问的情况下,链表在这方面不应该比数组差多少)。基于数组的实现比单链表更好的地方正是在考虑分页和 CPU 缓存时。该 MS 寻求的解决方案在纯随机访问情况下更糟,但在分页很重要的实际情况下更好,因此他们正在关注分页的影响。

当然,从外部看,这并不明显——也不应该如此。从外部看,我们想要像队列一样工作的东西;使内部高效是一个不同的问题。

这些担忧也以其他方式得到解决。例如,GC 的工作方式最大限度地减少了必要的分页量,因为它的移动对象不仅减少了碎片,而且减少了页面错误。其他集合也以使分页频率低于最直接解决方案建议的方式实现。

这只是我看过的一些事情中让我印象深刻的事情。我敢打赌,在 .NET 团队工作的许多其他地方也考虑到了这些问题。其他框架也是如此。考虑到 Cliff Click 在他的 Java 无锁哈希表(我真的完成了对我的 C# 实现的检查)方面反复提到的一大性能问题,除了无锁并发(练习的重点)是缓存行; 这也是他不会忽视的另一个性能问题!

还要考虑一下,大多数集合的大多数用途无论如何都将适合一页!

如果您正在实现自己的集合,或者将标准集合投入到特别大量的使用中,那么这些是您需要考虑的事情(有时“不,不是问题”就足够了,有时不是),但这并不并不是说他们还没有考虑到我们从 BCL 中得到什么。

于 2010-10-15T02:30:50.377 回答
0

如果您有一个特别特殊的场景和算法,那么您可能会从这种优化中受益。

但一般来说,当重新实现 CLR 框架的核心部分时(在我可能添加的 CLR 之上,即在托管代码中),您比 CLR 团队更有效地完成它的机会非常渺茫。所以我不会推荐它,除非你已经对你当前的实现进行了分析,并且已经确定了与内存中数据的局部性相关的问题。即便如此,通过调整算法以更好地使用 CLR 内存管理方案,然后尝试绕过或解决它,您将获得更多收益。

于 2010-10-03T22:44:15.687 回答