Performance 内存分配功能是否指示不再使用内存内容?

Performance 内存分配功能是否指示不再使用内存内容?,performance,memory,memory-management,dynamic-memory-allocation,cpu-cache,Performance,Memory,Memory Management,Dynamic Memory Allocation,Cpu Cache,当处理某些数据流(例如来自网络的请求)时,通常会使用一些临时内存。例如,一个URL可能被分割成多个字符串,每个字符串可能从堆中分配内存。这些实体的使用通常是短暂的,内存总量通常相对较小,应该适合CPU缓存 当用于临时字符串的内存被释放时,字符串内容很可能只存在于缓存中。但是,CPU不知道内存被释放:释放只是内存管理系统中的一个更新。因此,当CPU缓存用于其他内存时,CPU可能会不必要地将未使用的内容写入实际内存,除非内存释放以某种方式向CPU指示不再使用该内存。因此,问题变成: 释放内存的内存管

当处理某些数据流(例如来自网络的请求)时,通常会使用一些临时内存。例如,一个URL可能被分割成多个字符串,每个字符串可能从堆中分配内存。这些实体的使用通常是短暂的,内存总量通常相对较小,应该适合CPU缓存

当用于临时字符串的内存被释放时,字符串内容很可能只存在于缓存中。但是,CPU不知道内存被释放:释放只是内存管理系统中的一个更新。因此,当CPU缓存用于其他内存时,CPU可能会不必要地将未使用的内容写入实际内存,除非内存释放以某种方式向CPU指示不再使用该内存。因此,问题变成:

释放内存的内存管理功能是否以某种方式表示可以丢弃相应内存的内容?是否有方法向CPU指示不再使用内存?(至少,对于某些CPU:显然,架构之间可能存在差异)由于不同的实现可能会在质量上有所不同,可能会做也可能不会做任何花哨的事情,问题实际上是是否有任何内存管理实现指示内存未使用


我确实意识到,始终使用相同的内存可能是一种缓解策略,以避免对实际内存进行不必要的写入。在这种情况下,将使用相同的缓存内存。类似地,内存分配可能总是产生相同的内存,同时也避免了不必要的内存传输。但是,我可能不需要依赖这些技术中的任何一种。这在很大程度上取决于您使用的实现和库。分配和释放的内存往往会很快重新分配。大多数分配都是小数据块,比需要时写入备份存储器的页面小得多


如今,RAM的大小通常非常大,以至于当操作系统开始将脏页写入备份存储时,无论发生什么,您都会遇到麻烦。如果你有16 GB的RAM,你将不会写入100千字节或1兆字节,你将写入千兆字节,你的计算机将慢到爬行。用户可以通过不使用占用过多内存的应用程序来避免这种情况

相当多的分配器将“空闲块列表”存储在空闲块中。即,当您调用该释放函数时,分配的块被拼接到空闲列表中,这可能意味着使用前向和后向指针覆盖旧数据。这些写入操作将至少覆盖分配的第一部分

分配器使用的第二种技术是积极回收内存。如果下一次分配可以与最新的释放匹配,那么很可能缓存没有刷新到主内存


你的想法的问题是,每一篇文章实际上并没有那么昂贵,要想弄清楚哪些东西可以被丢弃,需要花费相当多的簿记费用。实际上,您不能进行系统调用。这意味着您需要在每个应用程序中进行簿记(这是合理的:释放这些小块通常会将内存返回给应用程序,而不是操作系统)。这反过来意味着应用程序需要了解CPU缓存设计,这绝不是常数。应用程序甚至需要知道不同的缓存一致性方案

您在这里提出了许多相关问题。黑体字最容易回答。当你用类似于一般释放的方式释放内存时,你唯一要说的是“我不再需要这个了”。你还含蓄地说,“我不在乎你用它做什么”。这个“我不在乎”实际上就是你问题的答案。你不是说“你可以放弃这个”。你在说“我不管你是否丢弃它”

为了回答您关于CPU支持的问题,是一个基本的缓存一致性协议。
I
状态代表“无效”,这就是您如何实现所询问的“内存未使用”状态的方法。为了做到这一点,您需要创建一个具有非泛型语义的发布接口,也就是说,这种发布意味着“不再使用此内存,您应该避免将其写回主内存”。请注意,这种语义对CPU的行为有一个通用版本没有的要求。要实现这一点,您需要与CPU缓存协调分配内存,然后使用可用的CPU指令使缓存项无效。您几乎肯定需要编写汇编代码来完成这项工作,以避免使用显式缓存管理指令会导致对内存模型的不必要(和不正确)假设

我个人已经有一段时间不需要在这个级别上工作了,所以我不熟悉任何地方都可以使用什么,也就是说,这项技术是否可以合理地移植。英特尔CPU有
INVLPG
指令。这里的讨论应该是您关注的下一阶段的良好开端:

No。 您提到的缓存操作(将缓存内存标记为未使用并丢弃而不写回主内存)称为不写回的缓存线无效。这是通过一条特殊指令执行的,该指令的操作数可以(也可以不)指示要失效的缓存线地址

在我熟悉的所有体系结构中,这条指令都是特权,我认为这是有充分理由的。这意味着用户模式代码不能使用该指令;只有内核可以。否则,可能出现的不当欺诈、数据丢失和拒绝服务的数量将不断增加