我正在用C#编写一个B -tree实现,我为我的应用程序选择的树实现有一个非常特定的结构,它具有缓存意识.要实现这些属性,它在树节点上具有严格的布局策略.
我想要的只是使用C#的fixed关键字表示固定大小的缓冲区:
public abstract class Tree<K, T> { }
sealed class Node<K, T> : Tree<K, T>
{
Node<K, T> right;
fixed Tree<K, T> nodes[127]; // inline array of 128 nodes
}
不幸的是,固定大小的缓冲区只能用于原始值类型,如int和float.只使用普通数组会添加指针间接,这会破坏此树类型的缓存友好属性.
我也无法生成128个字段并使用指针算法来提取我想要的字段,因为there are no conversions between pointer types and managed objects.
关于唯一剩下的就是生成128个字段,其中索引器根据交换机选择正确的字段(不能快速),或者将其写为C库并使用P / Invoke,这也会破坏性能.
有什么建议?
解决方法:
使用C/C++LI.这使您可以完全控制布局,就像C一样,但托管/非托管转换的成本从p / invoke大大减少(可能根本不需要额外的成本).
不幸的是,托管代码不适合“缓存意识”工作:在托管堆内部,您无法避免错误共享. C/C++LI允许您使用非托管分配器,因此您不仅可以保持数据连续,还可以与缓存行对齐.
另请注意:使用class关键字会创建一个“引用类型”,它已经添加了您希望避免的间接级别.通过一些重组,您可以使用结构和数组,而不再使用您建议的代码.