簡體   English   中英

解析內存分配器的正確方法

[英]Correct way to profile a 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);

在分配然后立即釋放100k塊100k次時,沒人關心[*]您的分配器是比分配器快還是慢。 那不是常見的內存分配模式(對於任何發生這種情況的情況,可能有比使用內存分配器更好的優化方法。例如,通過alloca使用堆棧或使用靜態數組)。

人們非常關心您的分配器是否會加快其應用程序。

選擇一個真實的應用程序。 使用兩個不同的分配器研究其在處理大量分配任務時的性能,並進行比較。 然后研究更多分配繁重的任務。

僅舉一個例子,您可以比較一下啟動Firefox和加載StackOverflow首頁的時間。 您可以模擬網絡(或至少使用本地HTTP代理),以從測試中刪除大量隨機變化。 您還可以使用探查器來查看在malloc花費了多少時間,從而了解了任務是否是分配繁重的,但是請注意,諸如“過量提交”之類的東西可能意味着並非所有的內存分配成本都在malloc支付了。

如果您編寫分配器是為了加速自己的應用程序,則應使用自己的應用程序。

需要注意的一件事是,在最壞的情況下,人們通常希望分配器具有良好的行為。 就是說,如果您的分配器在大多數情況下比默認速度快99.5%,那一切都很好,但是如果內存碎片化時分配器的表現相對較差,那么最終您會丟失,因為Firefox運行了幾個小時並且那么就無法再分配內存並崩潰。 然后,您就會了解為什么默認設置花了這么長時間來處理看起來很瑣碎的任務。

[*]這看起來很刺耳。 沒人在乎它是否苛刻;-)

您要測試的所有實現都丟失了,正在檢查數據包的當前大小是否與先前油炸的相同:

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

為內存創建高效的malloc / free函數是很簡單的,直到內存沒有碎片為止。 挑戰是當您分配大量不同大小的內存,然后嘗試釋放一些內存,然后分配一些沒有特定順序的內存。

您必須檢查針對哪個庫進行了測試,並檢查該庫針對哪些條件進行了優化。

  • 碎片化的內存處理效率
  • 快速釋放,快速malloc(您可以使一個O(1)),
  • 內存占用
  • 多處理器支持
  • 重新分配

檢查他們正在處理的現有實現和問題,並嘗試改善或解決他們遇到的困難。 嘗試找出用戶對庫的期望。

根據此假設進行測試,而不僅僅是您認為重要的某些操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM