编程中的内存管理是否已成为无关紧要的问题?
内存管理(或控制)实际上是我使用C和C ++的主要原因。
内存现在相对便宜。
没有快速记忆。我们仍在查看少量寄存器,例如i7上L1的32KB数据高速缓存,L2的256KB和L3 /内核的2MB。说:
如果我们不是在对工作内存(即嵌入式系统等)有严格限制的目标平台上说话,那么今天选择通用语言时是否应该考虑内存使用情况?
总体而言,内存使用情况可能并非如此。我有点不切实际,因为我不喜欢这样的记事本,即需要50 MB的DRAM和数百MB的硬盘空间,即使我有多余的备用空间。我已经待了很长时间了,看到这样一个简单的应用程序占用了相当大的内存来处理应该以千字节为单位的内容,这让我感到很奇怪,而且有点讨厌。就是说,如果我仍然遇到这样的事情,并且仍然很好并且反应迅速,我也许可以和我自己住在一起。
内存管理在我的领域对我很重要的原因通常不是减少太多内存使用。如果没有频繁访问该内存,则数百兆的内存使用不一定会以任何不平凡的方式减慢应用程序的运行速度(例如:仅在单击按钮或其他形式的用户输入时,除非您在谈论韩国星际争霸玩家,他们每秒可能会点击一百万次)。
在我的领域中,重要的原因是要使内存紧密和紧密地连接在一起,这些内存在那些关键路径中经常被访问(例如,遍历每个帧)。我们不想每次访问只需要在一个循环中访问的一百万个元素中的一个元素时就丢失高速缓存。当我们将内存从慢速内存大块下移到快速内存(例如64个字节的缓存行)的层次结构中时,如果这64个字节全部包含相关数据,并且我们可以将多个值的数据容纳到这64个字节中,这将非常有用。如果我们的访问模式足以在驱逐数据之前全部使用。
即使我们有千兆字节,上百万个元素的频繁访问数据也可能仅跨越20兆字节。如果内存太紧且紧密在一起以最大程度地减少高速缓存未命中,那么在每个绘制的帧上循环遍历该数据的帧速率仍然存在很大差异,因此内存管理/控制非常有用。具有数百万个顶点的球面上的简单视觉示例:
上面的内容实际上比我的可变版本慢,因为它正在测试网格的持久性数据结构表示形式,但除此之外,我过去即使在一半的数据上也都难以达到这样的帧速率(不可否认,自从我奋斗以来,硬件变得更快了),因为我没有将网格数据的高速缓存未命中和内存使用降至最低的念头。在这方面,网格是我处理过的最棘手的数据结构,因为它们存储了如此多的相互依赖的数据,这些数据必须保持同步,例如多边形,边缘,顶点,用户想要附加的纹理贴图,骨骼权重,彩色图,选择集,变形目标,边缘权重,多边形材质等等等。
在过去的几十年中,我已经设计并实现了许多网格系统,它们的速度通常与它们的内存使用成正比。尽管我正在使用这种方法,但是比起初的内存要多得多,但是我的新网格系统比我的第一个设计(将近20年前)要快10倍以上,并且很大程度上是因为它们使用了大约1/10的内存。记忆。最新版本甚至使用索引压缩来填充尽可能多的数据,尽管解压缩会产生处理开销,但压缩实际上提高了性能,因为同样,宝贵的快速内存也很少。现在,我可以将一百万个多边形网格与纹理坐标,边缘压痕,材质分配等配合使用,并为其提供空间索引(大约30兆字节)。
这是可变的原型,具有超过800万个四边形,并在带有GF 8400的i3上采用了多分辨率细分方案(这是几年前的产品)。它比我的不可变版本要快,但由于我发现不可变版本非常容易维护并且性能影响还不错,因此没有在生产中使用。请注意,线框并不表示刻面,而是贴片(导线实际上是曲线,否则整个网格将为纯黑色),尽管刻面中的所有点均已被笔刷修改。
因此,无论如何,我只想在上面显示其中的一些内容,以显示一些具体的示例和领域,其中内存管理非常有帮助,并且希望人们不会认为我只是在胡说八道。当人们说内存是如此丰富和便宜时,我往往会有些恼火,因为这是在谈论诸如DRAM和硬盘之类的慢速内存。当我们谈论快速内存时,它仍然是如此的小而珍贵,真正关键的(即,通常情况下,并非针对所有情况)路径的性能与播放少量的快速内存并尽可能有效地利用它有关。 。
对于这种事情,使用一种语言是非常有帮助的,例如,允许您设计高级对象(例如C ++),同时仍然能够将这些对象存储在一个或多个连续数组中,并确保所有这些对象将被连续表示,并且每个对象没有任何不必要的内存开销(例如:并非所有对象都需要反射或虚拟分派)。当您真正进入那些对性能至关重要的领域时,通过这样的内存控制来摆弄对象池并使用原始数据类型来避免对象开销,GC成本并保持经常访问的内存,实际上可以提高生产率。在一起连续。
因此,在我的案例中,内存管理/控制(或缺少内存管理/控制)实际上是一个主要的原因,因为它决定了哪种语言可以最有效地帮助我解决问题。我确实确实编写了我的代码,这些代码不是性能至关重要的,为此,我倾向于使用很容易从C嵌入的Lua。