システムごとにプロファイリングとメモリプーリングを行う方法


8

各サブシステムの管理されたメモリプールのプロファイリングと維持に興味があったので、サウンドやグラフィックスなどで使用されているメモリの量に関する統計を取得できました。しかし、これを行うために機能するデザインは何でしょうか?複数のアロケーターを使用し、サブシステムごとに1つだけ使用することを考えていましたが、その場合、アロケーターのグローバル変数が発生します(または、私にはそれが見えるようになります)。私が見た/提案した別のアプローチは、単にnewをオーバーロードし、パラメータのアロケータを渡すことです。

私はここでバウンティを使ってスタックオーバーフローについて同様の質問をしましたが、それはおそらく私が漠然としているか、主題に関する知識を持つ十分な人々がいないかのようです。


私の答えを削除しました。私は戻って記事を読み、システムごとの割り当てを追跡するために使用されるプールはそれらに基づいていませんが、それらの記事の一部ではありません。それらの特定の記事を再度見つけることができれば、代わりにそれらをリンクします!ごめんなさい!
James

1
見てみましょうこのブログの記事イエス・デ・サントス・ガルシアによると。その中で、彼はサブシステムによるメモリの追跡と、さまざまなメモリ要件に対する複数のアロケータの使用について説明しています。

7
理論的なパラダイムに夢中にならないでください。グローバルに機能とデータが必要な場合は、グローバルに問題はありません。new / delete / malloc / freeのようなグローバル関数はすでにたくさんあります。必要なものを追加するだけで、仕事を完了できます。
Maik Semder

回答:


1

一部の人には曖昧に聞こえるかもしれない質問です;)

しかし、私はあなたがどこから来たのか知っていると思います。

これを実装する方法を選択するには、100万の選択肢があります。それらの選択のいくつかは、ターゲットプラットフォームと全体的な設計目標の両方に関係する必要があります。これらの考慮事項は、プラットフォームから設計を成長させるのに十分なさまざまな実装コストに十分満足できるようになるまで、そして最初に一般的な設計の懸念を解消するまで、すべての関係を断ち切ります。それまでは、複雑さ(管理の負担)や、気が変わった場合の削除や変更に対処するためにコストがかからない方法をいくつか紹介します...

目標がプールの使用の可能性を考慮して測定して割り当てることである場合、最初に、住みやすいコードの最小限のセットについて検討する必要があります。説明のために、クラスに不慣れな場合は、1つのクラス、つまりヒープを表すletを作成するか、代わりにハンドルまたはヒープ名を受け取る一連の関数を使用できます。正直に言うと、それは本当にセマンティクスの問題です。次の決定は、新規またはmallocです。多くの場合、低レベルの構成を扱っており、ほとんどの実装でnewがmallocを呼び出すことを知っているので、私はmallocに部分的です。 。しかし、私は何度も、システムのオーバーロードまたは新規のフックに関するコンポーネントを構築しています。そしてもちろん、中心的な問題や違いは、それが「新しい」ことです 'malloc'は気にしないので、割り当て前に型を知っている必要があり、mallocを使用すると、割り当て後に型に解決されます。詳細は、これらのタイプの問題で設計上の決定を行うためのアイデアといくつかのコンテキストを提供することです:)

ここで説明する方が簡単なので、クラスとmallocを選択しますが、結局それは重要ではありません。内部構造は、他の全体的な設計と比較して、材料の違いがほとんどないことになります。

したがって、この仮説では、私は最終的に7〜8個の実際のサブシステムクラスのインスタンス化を行い、割り当てと解放のために数十万の呼び出しを予測する可能性があることを知っています。私の好奇心と本当の推力の多くは、実際にはサイズとプロファイルの側面に関するものであるため、アプリのパフォーマンスに負担をかけたくありません。まず、アプリの残りの部分全体に実装するまでの過程をたどるとき、私はそれを釘付けにされるまで、すべてをオープンにして公開することに決めるかもしれません。構造体はこれをうまく行います。's_'は、統計用に明確に意図されている変数を示します。

struct Mem
{
  int s_allocs;
  int s_frees;
  int s_peak;
  int s_current;
  void* heap; // if you wanted to go into having real actual separate heaps, else ignore
  void* alloc(int size);
  void free(void* p);

  Mem() {memset(this,0,szieof(Mem));}  // want this to be inlined with the call site constructor (a design decision example)
}

class MySubSystem
{
   Mem mem;
   ....  you get the idea
}

これは 非常に多くの分野で軽量で、これを使いたいと思っていたところから肉付けを始めるのに最適な場所です。そして、あなたはすぐに問題を抱えています、あなたはどのようにして解放されたアイテムのサイズを知っていますか?(これはほとんどすべてのアプローチで解決する問題です。)これはゲームフォーラムなので、最初の数バイトをサイズでドープすることを検討するか、他の方法でラップするか覚えておく必要があります。ほとんどのゲーム開発者の感性は、ドーピングに対してあまり多くあるべきではなく、私がすでにテキストの壁を作ったことを考えると、その最も単純な例です。基本的には次のようになります。サイズが一貫している場合は、ほぼ無料で、固有の配置を破壊するのを助けることができるかどうかは知りません。したがって、 "s_allocs ++; s_total + = size; uint64 * p =(uint64 *)malloc / calloc(size + = 8); * p = 0xDEADDAED00000000 | サイズ; return p + 1; "ここで、割り当ては4GB未満になり、uint64は、コンパイラが64ビットの符号なしintであると考えているものであり、無料で健全性の値を確認できます。

これは、要件を満たす最低限のコストで最低限のコストを実現するための1つの方法です。しますプロファイリングまたは管理のスコープ内にある場合は、仮想関数を持つクラスの割り当てに対処します。これは、使用しているc ++環境のサイズが、オーバーロードしたり、フックしたりせずに必要な場合、またはいずれかのコンストラクターに依存している場合に予測できません。他の「init」関数では処理できない奇妙な方法。それ以外の場合は、キャストはクラスであり、クラスは任意の割り当てであり、すべて同じです。あなたが新しいことに部分的であり、固有の仮想テーブルまたはコンストラクタのセマンティクスが必要な場合は、新しくフックする必要がありますが、それはまったく別の動物であり、新しいニーズを実行していることを確認するために本当に研究する必要があり、信号を送る必要がありますこれが適用されるバケットを処理する新しいコード。しかし、それ以外は上記の概念は同じです。

さらに重要なことに、これはあなたの脳を動かし、うまくいけば、あなたが必要とするものと許容値との線に沿って、カーテンの後ろをもう少し見てきたはずです。ウィザードはありません:)


割り当てと解放にテンプレート関数を使用していた場合、解放(および割り当て)に必要なサイズを決定することは問題になりません。
API-Beast

1
ポイントは、特定の抽象化を提示するのではなく、任意の抽象化を選択するための基礎を提供するために、根本的な問題を示すことでした。すべてにトレードオフがあります。サイズの知識は、解放の行為ではなく統計のために必要です。
Celess

1

このデータのためにゲームに何かを実装する必要はありません。Massif Valgrindなどのツールは、デバッグシンボルからすべての必要なデータを抽出できます。Massif VisualizerでMassifのダンプを表示できます。


4
残念ながら、ほとんどのグラフィカルゲームはValgrindを実行するシステム上で開発されることはないと思います。
Kylotan

1

独自のメモリアロケータを作成しないことを強くお勧めします。破損検出などの優れたデバッグ機能を備えた安定した信頼性の高いテスト済みのものが必要です。最も重要なのは、信頼できる統計情報を備えていることです。これは簡単な作業ではなく、多くの落とし穴があります。たとえば、次のような便利で使いやすいものがあります。

ダグリーアロケーター

メモリ空間の概念が付属しており、サブシステムごとに1つ使用できます。高度に最適化されており、優れた統計情報と実行時情報を提供します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.