タグ付けされた質問 「memory-efficiency」

情報を整理して保存し、メモリを最大限に活用しながら、可能な限り少量のメモリを使用する方法。


8
彼らはそれをどうしましたか?テラリアの何百万ものタイル
私はTerrariaに似たゲームエンジンを主に挑戦として取り組んできましたが、そのほとんどを理解しましたが、何百万もの相互作用/収穫可能なタイルをどのように扱うかについて頭を包み込むように思えませんゲームは一度に持っています。私のエンジンでは、Terrariaで可能なことの1/20である約500.000のタイルを作成すると、フレームレートが60から約20に低下します。気を付けてください、私はタイルで何もしていません。メモリに保存するだけです。 更新:私が物事を行う方法を示すためにコードが追加されました。 これは、タイルを処理して描画するクラスの一部です。犯人は「foreach」の部分で、空のインデックスも含めてすべてを繰り返すと推測しています。 ... public void Draw(SpriteBatch spriteBatch, GameTime gameTime) { foreach (Tile tile in this.Tiles) { if (tile != null) { if (tile.Position.X < -this.Offset.X + 32) continue; if (tile.Position.X > -this.Offset.X + 1024 - 48) continue; if (tile.Position.Y < -this.Offset.Y + 32) continue; if (tile.Position.Y > -this.Offset.Y + …

6
2Dゲームの大きなビデオメモリ要件をどのように解決しますか?
2Dゲームの大きなビデオメモリ要件をどのように解決しますか? Allegro C / C ++で2Dゲーム(Factorio)を開発していますが、ゲームコンテンツの増加に伴い、ビデオメモリ要件が増加するという問題に直面しています。 現在、最初に使用される画像に関するすべての情報を収集し、これらの画像を可能な限りすべてトリミングして、可能な限り緊密に大きなアトラスに整理します。これらのアトラスはビデオメモリに保存され、そのサイズはシステムの制限に依存します。現在、通常は最大8192x8192の2つの画像であるため、256Mb〜512Mbのビデオメモリが必要です。 このシステムは、カスタム最適化とレンダリングスレッドと更新スレッドの分割により、60 fpsで何万枚もの画像を画面に描画できるため、非常に有効です。画面には多くのオブジェクトがあり、大きなズームアウトを許可することが重要な要件です。さらに追加したいので、ビデオメモリの要件に問題が発生するため、このシステムは保持できません。 私たちが試したかったことの1つは、最も一般的な画像を含む1つのアトラスと、キャッシュとしての2つ目のアトラスを持つことです。画像は、必要に応じてメモリビットマップからそこに移動されます。このアプローチには2つの問題があります。 allegroでは、メモリビットマップからビデオビットマップへの描画が非常に遅くなります。 allegroのメインスレッド以外でビデオビットマップを操作することはできないため、実際には使用できません。 追加の要件は次のとおりです。 ゲームは決定論的である必要があるため、パフォーマンスの問題や読み込み時間によってゲームの状態が変わることはありません。 ゲームはリアルタイムであり、すぐにマルチプレイヤーにもなります。どんなコストでも最小のスタッターでさえ避ける必要があります。 ゲームのほとんどは、1つの連続したオープンワールドです。 このテストは、1x1から300x300までのサイズのバッチで、構成ごとに数回、10,000個のスプライトを描画することで構成されていました。Nvidia Geforce GTX 760でテストを行いました。 ソースビットマップが個々のビットマップ(アトラスバリアント)間で変更されていない場合、ビデオビットマップからビデオビットマップへの描画はスプライトごとに0.1usかかりました。サイズは関係ありませんでした ビデオビットマップからビデオビットマップへの描画、ソースビットマップの描画間での切り替え(非アトラスバリアント)は、スプライトごとに0.56usかかりました。サイズも関係ありませんでした。 メモリビットマップからビデオビットマップの描画は本当に疑わしいものでした。1x1から200x200のサイズはビットマップあたり0.3usかかったので、それほどひどく遅くはありません。サイズが大きくなると、201x201の9usから291x291の3116usへと、劇的に時間の増加が始まりました。 アトラスを使用すると、パフォーマンスが5倍に向上します。レンダリングに10ミリ秒かかっていた場合、アトラスを使用すると、フレームあたり100,000スプライトに制限され、それなしでは、20000スプライトの制限があります。これには問題があります。 また、シャドウのビットマップ圧縮と1bppビットマップ形式をテストする方法を探していましたが、Allegroでこれを行う方法を見つけることができませんでした。


2
障害物が動いている場合でもA *は効率的ですか?
経路探索について学び始めたばかりで、A *アルゴリズムを検討しています。私の主な関心は、これまでに見たすべての例が、計算する静的障害を示していることです。 動く障害物、たとえば他のキャラクターが動き回るなど、キャラクターが動き回る必要がある場合、フレームごとにアルゴリズムを実行する必要があると想定していますが、かなり高価になるのではないかと心配していますハードウェアが各移動アクターの各フレームを処理します。 A *は、障害物が動いている場合でも使用できるほど効率的ですか、または、動いている障害物をより雄弁に処理するパス検索の別の方法がありますか?

1
新しいオブジェクトを即座にインスタンス化するのではなく、オブジェクトプールの作成と使用を常に検討する必要があるのはなぜですか?
このパターンについて何度か読みました(ベストプラクティスの観点から)。 メモリ割り当て:新しいオブジェクトを即座にインスタンス化する代わりに、オブジェクトプールの作成と使用を常に検討してください。メモリの断片化を減らし、ガベージコレクタの動作を減らすのに役立ちます。 ただし、実際に何を意味するのかわかりません。どうすれば実装できますか? たとえば、Unity GameObjectのInstantiateメソッドを使用してをインスタンス化できますか? Instantiate(prefab, new Vector3(2.0F, 0, 0), Quaternion.identity); この使用は推奨されませんか?他に何を意味できますか?

3
ゲーム開発で使用されるメモリ割り当てパターン
私は独自のアロケーターメソッド(メモリプールやプロファイリングなどをサポートする)の作成を研究していますが、研究を続けるにつれて、ゲーム開発でこれがどのように行われるかを探していました。 どのようなメモリ割り当て手法を使用できますか、なぜそれが優れた手法なのでしょうか?

3
メモリー不足状態にどのように準備しますか?
これは、明確に定義された範囲のゲームにとっては簡単ですが、問題はサンドボックスゲームについてであり、プレイヤーは何でも作成および構築できます。 可能なテクニック: 上限のあるメモリプールを使用します。 定期的に不要になったオブジェクトを削除します。 回復メカニズムとして後で解放できるように、最初に余分な量のメモリを割り当てます。約2〜4 MBです。 これは、16 GB PCとは異なり、メモリが通常制限されているモバイル/コンソールプラットフォームで発生する可能性が高くなります。メモリの割り当て/割り当て解除を完全に制御でき、ガベージコレクションが関与していないことを前提としています。これが、これをC ++としてタグ付けする理由です。 私が話していないですので、予めご了承ください効果的なC ++項目7「メモリ不足の条件のために準備して、」それは、関連だにもかかわらず、私はより多くのあなたが、通常は何をより詳細に制御を持っているゲーム開発に関連する答えを見たいのですが、ハプニング。 質問をまとめると、メモリコンソール/モバイルが限られているプラ​​ットフォームをターゲットにしている場合、サンドボックスゲームのメモリ不足状態にどのように対応しますか?

1
オーディオファイルを2倍速でエクスポートすると、ゲームエンジンが半速で再生されるという欠点がありますか?
ゲームのファイルサイズを削減したいのですが、音楽とSFXがかなりの部分を占めています。 120bpmで曲またはサウンドエフェクトを作成し、DAWまたはスタンドアロンプ​​ログラムを使用してテンポとピッチを2倍にした後、新しい倍速オーディオファイルを録音すると、元のファイルサイズの半分になります(曲の長さが半分)。次に、ゲームエンジン(Unity)を使用して240bpmオーディオファイルを半分の速度で再生するので、今では正常に聞こえます。アーチファクトや歪みはありません。 そこで質問があります:半分の速度でプレイするために処理能力のようなものを犠牲にしているのですか?私は半分のサイズのファイルを読み込んでいるので、どこかで何らかのトレードオフが必要になりますか?私は彼らの正しい心の誰もこれをしないだろうと感じていますが、なぜですか?

4
動的メモリ割り当てとメモリ管理
平均的なゲームでは、シーンには数百または数千のオブジェクトがあります。デフォルトのnew()を介して動的に銃の弾丸(弾丸)を含むすべてのオブジェクトにメモリを割り当てることは完全に正しいですか? ダイナミックアロケーション用のメモリプールを作成する必要がありますか、これを気にする必要はありませんか?ターゲットプラットフォームがモバイルデバイスの場合はどうなりますか? モバイルゲームでメモリマネージャーが必要ですか?ありがとうございました。 使用言語:C ++; 現在Windowsで開発されていますが、後で移植する予定です。

2
オフスクリーンAIを処理する良い方法は?
例えば: 世界に10の部屋があるとしましょう。 そして、世界には10のエンティティが住んでいるとしましょう。 また、各エンティティには独自の「毎日のルーチン」があり、部屋で特定のアクションを実行し、部屋間を移動することもできます。 プレーヤーは一度に1つの部屋にしか入ることができないので、他のエンティティが他の部屋で画面外で実行しているアクションを追跡する良い方法は何ですか? 最も簡単なオプションは、すべてのフレームで10個のエンティティのそれぞれをチェックし、それらの位置/状態をチェックして、エンティティがいつでもプレイヤーがいる部屋にいるかどうかを判断することです。 (ただし、これは、特に部屋/エンティティの量が増加するにつれて、本当にリソースが重いと感じます。) 別のオプションは、ゲームの開始から経過した時間を追跡することです。各エンティティは、そのパターンがプレーヤーのいる部屋と交差するかどうかをチェックします。エンティティはこの特定の時間に同じ部屋にあると想定され、プレイヤーが現在の部屋と交差しないパターンのエンティティは、プレイヤーがパターンと交差する部屋に入るまで何もせず、その時点でのみかどうかを計算しますレンダリングする必要があります。(しかし、部屋と対話する場合、その時点での位置を決定するために、ルートと交差する部屋の状態を常に確認する必要がありますが、それはそれほど素晴らしいことではありません。) 私がやってきた3番目のオプションは、まずプレイヤーの場所と交差するルートのみを見て(前述のとおり)、次に部屋に入ると、プレイヤーがその部屋にいるかどうかを確認し、そうでない場合は部屋の状態と次の部屋に進むのにどれくらい時間がかかりますか。たとえば、管理人のNPCが部屋に入り、部屋の状態を確認し、プレイヤーによるこぼれがあることを確認し、それを掃除するのにかかる時間と経路がかかる時間を計算します。時間は次の部屋に入るためです。プレイヤーが部屋にいるかどうかを確認するだけです。レンダリングのためのNPCの正確な位置は、プレイヤーが部屋に入ったときにのみ計算されます。 しばらくブレインストーミングした後、私は3番目のオプションに来ましたが、おそらくこれらのようなものを処理するための既知のまたはより良い方法があるのだろうかと思いましたか?

3
C ++標準ライブラリの実装を比較/比較するドキュメントはありますか?[閉まっている]
閉まっている。この質問はトピック外です。現在、回答を受け付けていません。 この質問を改善したいですか? 質問を更新して、 Game Development Stack Exchangeで話題になるようにします。 4年前に閉鎖されました。 (これはゲームプログラミングそのものではありませんが、歴史上、すべての大規模なゲームがこれらのことを心配していると言っていても、これを早めに最適化しないように言われると確信しています) さまざまなC ++標準ライブラリ実装間のパフォーマンス、特にメモリ使用量の違いをまとめたドキュメントはどこにありますか?一部の実装の詳細はNDAによって保護されていますが、STLportとlibstdc ++とlibc ++とMSVC / Dinkumware(vs. EASTL?)との比較は非常に役立つようです。 特に、次のような質問に対する答えを探しています。 どのくらいのメモリオーバーヘッドが標準コンテナに関連付けられていますか? 仮に宣言されただけで動的割り当てを行うコンテナがある場合、どのコンテナですか? std :: stringはコピーオンライトを行いますか?短い文字列の最適化?ロープ? std :: dequeはリングバッファーを使用しますか?

1
エンティティコンポーネントシステムのゲームエンジンでCPUキャッシュを活用するにはどうすればよいですか?
CPUキャッシュを賢く使用するための優れたアーキテクチャであるECSゲームエンジンのドキュメントをよく読みます。 しかし、CPUキャッシュの利点を理解することはできません。 コンポーネントが連続したメモリの配列(またはプール)に保存されている場合、コンポーネントを順番に読み取る場合にのみCPUキャッシュを使用するのが良い方法です。 システムを使用する場合、特定のタイプのコンポーネントを持つエンティティのリストであるエンティティリストが必要です。 ただし、これらのリストは、順番ではなくランダムな方法でコンポーネントを提供します。 それでは、キャッシュヒットを最大化するECSを設計する方法は? 編集: たとえば、物理システムには、RigidBodyおよびTransformコンポーネントを持つエンティティのエンティティリストが必要です(RigidBodyのプールとTransformコンポーネントのプールがあります)。 したがって、エンティティを更新するためのループは次のようになります。 for (Entity eid in entitiesList) { // Get rigid body component RigidBody *rigidBody = entityManager.getComponentFromEntity<RigidBody>(eid); // Get transform component Transform *transform = entityManager.getComponentFromEntity<Transform>(eid); // Do something with rigid body and transform component } 問題は、entity1のRigidBodyコンポーネントがそのプールのインデックス2にあり、entity1のTranformコンポーネントがそのプールのインデックス0にあることです(一部のエンティティは他のコンポーネントを持たず、エンティティを追加/削除するため/ランダムにコンポーネント)。 コンポーネントがメモリ内で連続している場合でも、それらはランダムに読み取られるため、キャッシュミスが多くなります。 ループ内の次のコンポーネントをプリフェッチする方法がない限り?

1
glDrawArraysとglDrawElementsの違い
OpenGL ESの上で私の心をリフレッシュしている間、私は出くわしたglDrawArraysとglDrawElements。 私はそれらがどのように使用されるかを理解し、なぜそれらが異なるのかを理解しています。 私が理解していないように見えるのは、glDrawElements描画呼び出しを保存する方法がわからないということです(描画呼び出しの保存は、私が読んだほとんどの本で言及されている説明なので、ここで言及します)。 2つの三角形を使用して正方形を描こうとした単純なシナリオを想像してみてください。 を使用するglDrawArraysときに使用する6つの頂点のセットglDrawElementsが必要です。6つの要素を持つインデックス配列に加えて、4つだけ必要です。 上記を踏まえて、ここに私が理解していないものがあります: glDrawElementsインデックス配列(正方形の場合は6つのインデックス)を使用して、4つの要素(6回)を持つ頂点配列にインデックスを付ける必要がある場合、どのように描画呼び出しを保存できますか?言い換えれば、glDrawElementsそれでも合計6回の描画呼び出しが必要になるということglDrawArraysですか? glDrawElementsそれでも2つの配列、つまり頂点とインデックスの2つの配列が必要な場合、どのように保存スペースを使用しますか? 2つの三角形から正方形を描画する場合、簡単にするために、glDrawElements(頂点配列に4項目、インデックス配列にglDrawArrays6項目)および(頂点配列にのみ6項目)の描画呼び出しを個別に何回行う必要がありますか? ありがとう。

6
カメラビューの外側にあるゲームオブジェクトは、Unityのコンピューター/モバイルリソースを消費しますか?
一体で、カメラに表示されず、ゲームの実行中にレンダリングされないゲームオブジェクトがシーンにあるとします。 これらのゲームオブジェクトは、ゲームの実行中にコンピューター/モバイルリソースを消費しますか? このような使用法の詳細はどこにありますか?

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