1

我编写了一个内存分配器,它(据说)比使用 malloc/free 更快。我已经编写了一小部分代码来测试它,但我不确定这是否是分析内存分配器的正确方法,谁能给我一些建议?

这段代码的输出是:

Mem_Alloc: 0.020000s
malloc: 3.869000s
difference: 3.849000s
Mem_Alloc is 193.449997 times faster.

这是代码:

int i;
int mem_alloc_time, malloc_time;
float mem_alloc_time_float, malloc_time_float, times_faster;
unsigned prev;

// Test Mem_Alloc
timeBeginPeriod (1);
mem_alloc_time = timeGetTime ();

for (i = 0; i < 100000; i++) {
    void *p = Mem_Alloc (100000);
    Mem_Free (p);
}

// Get the duration
mem_alloc_time = timeGetTime () - mem_alloc_time;

// Test malloc
prev = mem_alloc_time; // For getting the difference between the two times
malloc_time = timeGetTime ();

for (i = 0; i < 100000; i++) {
    void *p = malloc (100000);
    free (p);
}

// Get the duration
malloc_time = timeGetTime() - malloc_time;
timeEndPeriod (1);

// Convert both times to seconds
mem_alloc_time_float = (float)mem_alloc_time / 1000.0f;
malloc_time_float = (float)malloc_time / 1000.0f;

// Print the results
printf ("Mem_Alloc: %fs\n", mem_alloc_time_float);
printf ("malloc: %fs\n", malloc_time_float);

if (mem_alloc_time_float > malloc_time_float) {
    printf ("difference: %fs\n", mem_alloc_time_float - malloc_time_float);
} else {
    printf ("difference: %fs\n", malloc_time_float - mem_alloc_time_float);
}

times_faster = (float)max(mem_alloc_time_float, malloc_time_float) /
    (float)min(mem_alloc_time_float, malloc_time_float);
printf ("Mem_Alloc is %f times faster.\n", times_faster);
4

2 回答 2

0

您正在测试的所有实现都缺少检查当前数据包的大小是否与之前炒过的相同:

if(size == prev_free->size) 
{
     current  = allocate(prev_free);
     return current; 
}

在内存没有碎片之前,为内存创建高效的 malloc/free 函数是“微不足道的”。挑战是当您分配大量不同大小的内存并尝试释放一些然后分配一些没有特定顺序的内存时。

您必须检查您测试的库并检查该库针对哪些条件进行了优化。

  • 去碎片化的内存处理效率
  • 快速免费,快速 malloc(您可以制作任何一个 O(1) ),
  • 内存占用
  • 多处理器支持
  • 重新分配

检查他们正在处理的现有实现和问题,并尝试改进或解决他们遇到的困难。试着弄清楚用户对图书馆的期望。

对此假设进行测试,而不仅仅是您认为重要的一些操作。

于 2012-07-24T09:59:16.897 回答
0

没有人关心 [*] 你的分配器比他们的分配器快还是慢,在分配然后立即释放 100k 块 100k 次。这不是一种常见的内存分配模式(对于发生这种情况的任何情况,可能有比使用内存分配器更好的优化方法。例如,使用堆栈alloca或使用静态数组)。

人们非常关心你的分配器是否会加速他们的申请。

选择一个真实的应用程序。使用两种不同的分配器研究其在分配繁重的任务中的性能,并进行比较。然后研究更多分配繁重的任务。

仅举一个例子,您可以比较启动 Firefox 和加载 StackOverflow 首页的时间。您可以模拟网络(或至少使用本地 HTTP 代理),以从测试中删除大量随机变化。您还可以使用分析器来查看花费了多少时间malloc,从而查看任务是否分配繁重,但请注意“过度使用”之类的内容可能意味着并非所有内存分配成本都以malloc.

如果您编写分配器是为了加速您自己的应用程序,您应该使用您自己的应用程序。

需要注意的一件事是,人们通常在分配器中想要的是最坏情况下的良好行为。也就是说,如果您的分配器在大多数情况下比默认设置快 99.5%,那一切都很好,但如果内存碎片化时它的性能相对较差,那么您最终会失败,因为 Firefox 运行了几个小时并且然后无法再分配内存并摔倒。然后你就会意识到为什么默认设置会花费如此长时间来完成看似微不足道的任务。

[*] 这可能看起来很苛刻。没有人关心它是否苛刻;-)

于 2012-07-24T09:23:58.067 回答