正确分析内存分配器的方法

时间:2012-07-24 08:39:24

标签: c memory allocator

我编写了一个内存分配器(据说)比使用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);

2 个答案:

答案 0 :(得分:0)

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

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

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

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

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

需要注意的一点是,在最坏的情况下,人们在分配器中通常需要的是良好的行为。也就是说,如果你的分配器比大多数时候的默认值快99.5%,那就非常好了,但是如果内存碎片化时它的确比较差,那么你最终会失败,因为Firefox运行了几个小时然后不能再分配内存而且会失败。然后你就会意识到为什么默认值会花费很长时间而不是看似简单的任务。

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

答案 1 :(得分:0)

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

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

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

您必须检查您测试的库,并检查该库的优化条件。

  • 解密内存处理效率
  • 快速免费,快速malloc(你可以制作一个O(1)),
  • 内存足迹
  • 多处理器支持
  • 的realloc

检查他们正在处理的现有实施和问题,并尝试改善或解决他们遇到的困难。试着找出用户对库的期望。

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