【问题标题】:I need a simple yet efficient memory allocation algorithm我需要一个简单而高效的内存分配算法
【发布时间】:2012-01-16 14:09:09
【问题描述】:

我正在尝试实现自己的内存分配代码,它既简单又高效。任何想法我可以从哪里开始。 gcc 使用什么算法?

【问题讨论】:

  • 在 1..10 的尺度上,1 是最有效的,10 是最简单的,你的代码应该放在哪里?
  • 目前我更喜欢最简单的。
  • 您可能想阅读About Memory Allocators
  • 你应该首先确定你需要这个。即使在 Windows XP 下,标准分配器被认为是最糟糕的,我从来没有遇到任何 合理 的情况,其中分配是可衡量的事情或问题。当分配成为问题时,例如当您每秒执行超过 500 万次分配时,实际问题不是分配器,而是您的代码。少做。此外,许多“快速”分配器在不同情况下的行为非常不同,而“更好”的分配器总体上很可能更慢,而且以不明显的方式。

标签: c linux gcc x86-64


【解决方案1】:

这是一个经过数百次检查和实施的问题;您的实施可能会在非常特定的情况下工作,而其他任何地方都没有。在花费大量时间尝试自己解决这个问题之前,请考虑一下击败 gcc 的通用分配机制的现有实现:

http://goog-perftools.sourceforge.net/doc/tcmalloc.html

http://www.canonware.com/jemalloc/

您还可以通过查看源版本来查看 GCC/glibc 本身的实现:

http://gcc.gnu.org/releases.html

http://ftp.gnu.org/gnu/glibc/

Malloc 是 GNU C 库实现的一部分。

【讨论】:

  • glibc 使用调整的 ptmalloc2 = malloc.de/en,它本身基于 Doug Lea 的 malloc aka dlmalloc。
【解决方案2】:

始终返回 NULL 的 malloc 符合标准的字母。所以我建议

/* always return NULL, following the letter but not the spirit 
   of the standard */
inline void *malloc(size_t sz)
{  errno = ENOMEM;
   return NULL;   }

如果速度是您的主要标准,那么它的效率相当高。我没有声称它有用,但您没有要求有用。

真正的mallocs 很复杂,因为它们试图变得有用和高效。它们通常构建在现有的 syscalls 之上(如 Linux 上的 mmap(2)munmap 等......)并且它们经常尝试重用释放的内存。研究例如GNU libcmusl libc的相关源码

【讨论】:

    【解决方案3】:

    GCC 使用由目标平台的 C 库提供的 malloc()。对于 Linux,您可以在 GNU C 库中找到 malloc 的实现:http://repo.or.cz/w/glibc.git/blob/HEAD:/malloc/malloc.c

    对于通用分配器,您不太可能做得非常好,而且很可能做得非常糟糕,因为默认分配器已经针对许多不同的使用场景进行了多年调整。

    对于某些特殊用途的分配器,是的,击败通用分配器当然是可行的。

    【讨论】:

      【解决方案4】:

      如果你想要一个非常简单的方法:

      // 1 KB of data that can be allocated
      #define MAX_DATA 1024
      
      char pointers[MAX_DATA];
      int  currentOffset = 0;
      int ptrNum = 0;
      int sizes[MAX_DATA];
      
      void *malloc(int numBytes)
      {
          char *ptr = pointers + currentOffset;
      
          currentOffset += numBytes;
      
          if (currentOffset >= MAX_DATA)
              return NULL;
      
          sizes[ptrNum++] = numBytes;
      
          return ptr;
      }
      
      void free(void *ptr)
      {
          currentOffset -= sizes[ptrNum--];
      }
      

      请注意,需要按照分配内存的顺序来释放内存。

      【讨论】:

      • 准确来说,需要按照分配的保留顺序释放。
      猜你喜欢
      • 2020-01-28
      • 2012-10-01
      • 2019-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-16
      相关资源
      最近更新 更多