简体   繁体   English

如何在C ++中有效地管理内存/时间?

[英]How to efficiently manage memory/time in C++?

The case: 案子:

I wrote a minimax algorithm in Java, then I ported the code in C++, mantaining the same classes and methods. 我用Java编写了一个minimax算法,然后将代码移植到C ++中,并保留了相同的类和方法。 Then I valgrinded the C++ code until all memory leaks were fixed by putting delete functions in destructors (when possible). 然后我对C ++代码进行了评估,直到通过将delete函数放在析构函数中(如果可能)修复了所有内存泄漏。 When all leaks were fixed, I tested the algorithm on a tic-tac-toe game, which code was then ported identically in C++. 修复所有漏洞后,我在井字游戏中测试了该算法,然后将该代码以相同的方式移植到C ++中。 I was sure that the C++ version would have been more performant, however I was surprised seeing that 100 (not random) instances of the game were solved in 125 seconds by C++ version while the Java version solved them in 30 seconds! 我确定C ++版本的性能会更高,但是我惊讶地发现C ++版本在125秒内解决了100个(非随机)游戏实例,而Java版本在30秒内解决了它们! Then, using System Monitor I checked the memory usage of the two programs: the Java code memory usage at the end of the test increased roughly 20% while with the C++ version the memory only increased of 5%. 然后,使用系统监视器,我检查了两个程序的内存使用情况:测试结束时Java代码的内存使用率大约增加了20%,而C ++版本的内存仅增加了5%。

Then, at my eyes, it's clear that this delete policy is memory saving but kills time performance, which is not what I want, at least in this case. 然后,在我看来,很明显,此delete策略可以节省内存,但会破坏时间性能,这至少在这种情况下不是我想要的。 Is there another deletion policy to better design softwares which requires small runtime but allow high memory usage? 是否有另一种删除策略可以更好地设计软件,从而需要较少的运行时间但允许较高的内存使用量?

malloc and delete have to do more work as malloc和delete必须做更多的工作,因为

  • memory is not allocates in a multi-threaded way 内存不是以多线程方式分配
  • memory is not allocated continuously in memory, but for regions of free memory. 内存不会在内存中连续分配,而是分配给可用内存区域。
  • delete is performed in the current thread. delete在当前线程中执行。
  • for 64-bit applications you may find the memory alignment is 16 bytes instead of 8 bytes, resulting in more padding per allocation. 对于64位应用程序,您可能会发现内存对齐是16个字节而不是8个字节,从而导致每个分配的填充量更大。

Possible solutions in C++ C ++中可能的解决方案

  • don't use the heap so much, allocating on the stack is much faster than Java's or C++'s heap, and it is multi-threaded. 不要过多地使用堆,在堆栈上的分配比Java或C ++的堆快得多,并且它是多线程的。
  • allocate blocks of objects at once if possible eg an array of objects is one allocation in C++ instead of N+1 in Java. 尽可能一次分配对象块,例如,对象数组是C ++中的一种分配,而不是Java中的N + 1。
  • use a multi-threaded allocator. 使用多线程分配器。 C++ supports multiple allocators. C ++支持多个分配器。
  • use an arena allocation pattern. 使用竞技场分配模式。 If you have a large data structure with lots of nodes, you can allocate blocks of N node at a time and when you free such nodes, build a linked list of free node. 如果您的数据结构较大且包含大量节点,则可以一次分配N个节点的块,并在释放此类节点时构建一个空闲节点的链表。 You need to do this with the nodes themselves. 您需要使用节点本身来执行此操作。 In this approach the whole data structure/arena is deallocated at once. 在这种方法中,整个数据结构/区域立即被释放。

In short, if you do a literal translation of Java code to C++, it may well be slower as this doesn't take advantage of all the optimisations C++ allows but Java doesn't. 简而言之,如果您将Java代码直接转换为C ++,则可能会很慢,因为这没有利用C ++允许的所有优化,而Java却没有。

BTW Java 6+ uses 32-bit references for up to 32 GB of memory. BTW Java 6+使用32位引用来存储多达32 GB的内存。 If you build a 64-bit C++ application, see if using 32-bit pointers/references/indexes is an option for you. 如果您构建64位C ++应用程序,请查看是否可以选择使用32位指针/引用/索引。

If you are constantly building a tree (with a lot of small dynamically allocated nodes) and tearing it down, you are in the most favorable case for garbage collection. 如果您一直在构建一棵树(具有许多动态分配的小节点)并将其拆除,那么最适合垃圾回收的情况。 You might want to use the Boehm collector with C++. 您可能想将Boehm收集器与C ++一起使用。 (IIRC, Boehm's benchmark, designed to show that garbage collection can be faster than manual allocation, does something very similar to this: builds large trees, then tears them down.) (Boehm的基准测试IIRC旨在显示垃圾收集比手动分配更快,它执行的操作与此非常相似:先构建大树,然后将其拆除。)

Alternatively, you could look into some sort of memory pool. 另外,您可以查看某种内存池。 This is not a beginner's technique in C++, but it isn't that difficult either. 这不是C ++的初学者技术,但也不是那么困难。 Or, rather than deleting the nodes, you put them onto a free list, to recycle later. 或者,不是删除节点,而是将它们放到空闲列表中,以供以后回收。 (When allocating, you look first to the free list, and only call new if it is empty.) Or combine the two. (分配时,您首先查看空闲列表,只有在它为空的情况下才调用new 。)或将两者结合。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM