C语言中内存页/块的实现

C语言中内存页/块的实现,c,linux,performance,memory,C,Linux,Performance,Memory,我想用C版本替换页面管理API的Java版本。C版本应该支持几乎无限的空间(耶!)和难以置信的速度(tm) 我还需要一个特殊的二进制搜索版本,但我可以自己做 问题是: 什么页面大小最合适 有C语言的人通常使用的标准框架吗 在开销、操作系统资源等方面,创建这些块的最佳大小是多少 访问这些块的最佳方法是什么 memcpy是现代CPU中最好的一个,还是我需要汇编程序来挤出一些东西 是否可以按页面大小对齐这些块,以便所有内容都从页面大小的倍数的实际物理地址开始 映射文件呢?有线索吗 目标平台主要是I

我想用C版本替换页面管理API的Java版本。C版本应该支持几乎无限的空间(耶!)和难以置信的速度(tm)

我还需要一个特殊的二进制搜索版本,但我可以自己做

问题是:

  • 什么页面大小最合适
  • 有C语言的人通常使用的标准框架吗
  • 在开销、操作系统资源等方面,创建这些块的最佳大小是多少
  • 访问这些块的最佳方法是什么
  • memcpy是现代CPU中最好的一个,还是我需要汇编程序来挤出一些东西
  • 是否可以按页面大小对齐这些块,以便所有内容都从页面大小的倍数的实际物理地址开始
  • 映射文件呢?有线索吗
目标平台主要是Intels Xeon v3和更新的Linux内核

[更新]

该解决方案用于管理高达1TB的内存。内存将用于表示分布式内存中数据库碎片的内存中表,该数据库的最终大小可能超过100TB

每一页都将是这些表中某一列的基本内存块,该列可以是数据列,也可以是索引。这些页面将使用值压缩技术,表示每个值从一个字节到8个字节的整数(定点数字)。此压缩对列是透明的

这些页面将是页面池的一部分。页面池本身是将页面分组在一起的大容量内存部件的列表

->页面池->*页面->*页面

现在的问题是关于寻址方案。我不想在这上面花费超过两天的时间,所以我只希望有一个图书馆这样做

--

现状:

页面池本身使用值压缩。根据页面大小的不同,它的地址是页面大小的倍数,最多为roundUp(log256(总内存/页面大小))=每个地址的字节数

因此,对于4KB页面,1TB内存需要32位页面地址

由于页面池可以动态增长,页面可以从一个位置移动到另一个位置,以便压缩页面空间以释放内存块,因此使用表将页面ID(在页面池中)映射到内存中的实际地址

因此,每分配4KB页面的开销为4字节=>0.1%的开销

此外,页面池还需要跟踪页面是否空闲/删除,以及第一个和最后一个空闲页面的位置以及未使用但已分配的页面数。因此将使用两个计数器和一个位图->8*3+pageCount/8作为额外开销

一旦空闲页面的数量超过一定时间,表可能会通过将一个页面复制到另一个页面来压缩,这需要锁定机制,可以重新用于其他内容。我还没有决定。因此会带来额外的开销

使用具有自定义页面大小(但二次幂)的多个页面池,可以使用简单的PageID作为指向页面实际地址的指针。一旦页面移动,地址指针就会改变

使用的页面池数量将允许更短的页面ID。例如,搜索索引的碎片的目标大小为1GB,一旦它变得相当大,就会使用复制页面的快速操作将其一分为二,但也能够将页面移动到池的某个部分,该部分仅分配给新的池,这意味着拆分池可能会导致很少的实际页面副本

因此,页面大小为4KB的GB会产生2^30-2^12=2^18=3字节的PageID,但如果索引加载正确,则可能平均使用2字节(值压缩可以使用最小值,根据最小值仅存储增量,并更新最小值必须更改的所有值)

因为我混合了C和Java,所以C中剩下的就是页面实现、页面池分配和地址表。其余部分使用Java完成

所以基本上,如果没有对这个的支持,也没有标准的库辅助,我必须自己做,对吗


有什么特别的说明吗?

Martin,归根结底,C语言的替换很可能比您当前的java实现快几个数量级,不管页面大小如何等等。。。。您的内存方案将在开发过程中确定。使用C,您可以在直接内存分配和使用级别工作,并且可以完全根据需要定制内存使用。您可以使用整个系统的虚拟内存,并且可以从1字节开始使用块。(以2的幂块进行分配是一个安全的起点)
memcpy
memove
都可以。你可以根据需要进行调整。我在“过于宽泛”和“主要基于观点”之间左右为难,因为两者之间有着密切的关系(不清楚你在问什么)。如果没有关于这个页面系统要做什么的信息,以及预期的使用模式,诸如此类的信息,我就不愿意尝试自吹自擂。此外,您还需要确定系统上总共有多少内存可用,以及系统上其他进程的工作负载,并且……嗯,需要大量信息才能给出有关调整大小问题的合理答案。没有一个标准的框架。