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

あなたのアロケータが彼らのアロケータより速いか遅いかを誰も気にしません[*]、割り当ててすぐに100kブロックを100k回解放します。これは一般的なメモリ割り当てパターンではありません(また、それが発生する状況では、メモリアロケータを使用するよりも最適化する方がおそらく良い方法があります。たとえば、静的配列を介してスタックをalloca使用するか、静的配列を使用します)。

人々はあなたのアロケータが彼らのアプリケーションをスピードアップするかどうかを大いに気にします。

実際のアプリケーションを選択してください。2つの異なるアロケータを使用して、割り当てが多いタスクでのパフォーマンスを調査し、それを比較します。次に、割り当てが多いタスクをさらに検討します。

一例として、Firefoxを起動してStackOverflowフロントページをロードする時間を比較できます。ネットワークをモックして(または少なくともローカルHTTPプロキシを使用して)、テストからランダムなバリエーションの多くを削除することができます。プロファイラーを使用して、どのくらいの時間が費やされmallocているか、つまりタスクが割り当て量が多いかどうかを確認することもできますが、「オーバーコミット」などは、メモリ割り当てのコストのすべてがで支払われるわけではないことに注意してくださいmalloc

独自のアプリケーションを高速化するためにアロケータを作成した場合は、独自のアプリケーションを使用する必要があります。

注意すべきことの1つは、アロケータに人々が望むのは、最悪の場合の良い行動であることが多いということです。つまり、ほとんどの場合、アロケータがデフォルトより99.5%速い場合は問題ありませんが、メモリが断片化したときにアロケータの速度が比較的悪い場合は、Firefoxが数時間実行されてその後、メモリを割り当てることができなくなり、フォールオーバーします。次に、些細な作業のように見えるものにデフォルトが非常に長い時間を要している理由を理解します。

[*]これは厳しいように思われるかもしれません。厳しいかどうかは誰も気にしません;-)

于 2012-07-24T09:23:58.067 に答える
0

テストしているすべての実装が欠落しているのは、パケットの現在のサイズが以前に揚げたものと同じであるかどうかをチェックすることです。

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

メモリが断片化されなくなるまで、メモリに対して効率的なmalloc/free関数を作成することは「簡単」です。課題は、さまざまなサイズのメモリを大量に割り当て、一部を解放してから、特定の順序なしで一部を割り当てようとする場合です。

テストしたライブラリを確認し、そのライブラリが最適化された条件を確認する必要があります。

  • 断片化されていないメモリ処理効率
  • 高速無料、高速malloc(いずれか1つのO(1)を作成できます)、
  • メモリーフットプリント
  • マルチプロセッサのサポート
  • realloc

彼らが扱っていた既存の実装と問題をチェックし、彼らが抱えていた問題を改善または解決しようとします。ユーザーがライブラリに何を期待しているかを理解してください。

重要だと思う操作だけでなく、この仮定をテストしてください。

于 2012-07-24T09:59:16.897 に答える