プログラミングにおけるメモリ管理は無関係な関心事になっていますか?
メモリ管理(または制御)は、実際にCとC ++を使用している主な理由です。
現在、メモリは比較的安価です。
高速メモリではありません。i7上のL1の32KBデータキャッシュ、L2の256KB、L3 /コアの2MBなど、まだ少数のレジスタを探しています。それは言った:
作業メモリに厳しい制限があるターゲットプラットフォーム(つまり、組み込みシステムなど)で話さない場合、今日汎用言語を選択する際にメモリ使用量を考慮する必要がありますか?
一般的なレベルでのメモリ使用量は、おそらくそうではありません。私は、たとえば50メガバイトのDRAMと数百メガバイトのハードディスクスペースを必要とするメモ帳のアイデアが好きではないという点で、少し非実用的です。私は長い間あちこちにいて、このような単純なアプリケーションがキロバイトで実行できることに対して比較的多くのメモリを必要とするのを見るのは奇妙で気分が悪いだけです。そうは言っても、もしそれが素晴らしく、反応が良ければ、そのようなことに出会った場合、私は自分自身と一緒に暮らすことができるかもしれません。
私の分野でメモリ管理が私にとって重要である理由は、一般的にメモリ使用量をそれほど減らすことではありません。数百メガバイトのメモリ使用は、そのメモリのどれにも頻繁にアクセスされない場合、必ずしも重要でない方法でアプリケーションの速度を落とすわけではありません(例:ボタンクリックまたは他の形式のユーザー入力時のみ、これは非常にまれですボタンを1秒間に100万回クリックする可能性のある韓国のStarcraftプレイヤーについて話しています)。
私の分野で重要な理由は、それらのクリティカルパスで非常に頻繁にアクセスされる(例:単一のフレームごとにループされる)メモリを密に近づけることです。毎フレームループですべてにアクセスする必要がある100万個の要素のうち1つだけにアクセスするたびにキャッシュミスが発生することは望ましくありません。64バイトのキャッシュラインなど、大きなメモリを低速のメモリから高速のメモリに階層を移動するときに、それらの64バイトにすべて関連データが含まれている場合、複数の要素に相当するデータをそれらの64バイトに収めることができれば、非常に役立ちます。データが追い出される前にすべてを使用するようなアクセスパターンがある場合。
ギガバイトがあっても、100万個の要素について頻繁にアクセスされるデータは20メガバイトにしかならない可能性があります。キャッシュミスを最小限に抑えるためにメモリが密集して密集している場合、描画されるフレームごとにフレームレートがループするため、フレームレートに大きな違いが生じます。これが、メモリ管理/制御が非常に役立つ場合です。数百万の頂点を持つ球の単純な視覚的な例:
メッシュの永続的なデータ構造表現をテストしているため、上記は実際に可変バージョンよりも遅くなりますが、それを除けば、その半分のデータでさえそのようなフレームレートを達成するのに苦労していました(確かに私の苦労以来ハードウェアは速くなっています) )メッシュデータのキャッシュミスとメモリ使用を最小限に抑えることができなかったためです。メッシュは、ポリゴン、エッジ、頂点、ユーザーがアタッチしたいテクスチャマップ、ボーンウェイトなど、同期を維持する必要がある相互依存データを非常に多く格納するため、この点で扱いにくい最も複雑なデータ構造の一部です。カラーマップ、選択セット、モーフターゲット、エッジウェイト、ポリゴンマテリアルなど。
私は過去数十年間に多くのメッシュシステムを設計および実装してきましたが、その速度は多くの場合メモリ使用量に非常に比例していました。作業を始めたときよりもはるかに多くのメモリを使用しているにもかかわらず、新しいメッシュシステムは最初の設計(ほぼ20年前)の10倍以上高速であり、想い出。最新バージョンでは、インデックス圧縮を使用してできるだけ多くのデータを圧縮します。また、解凍の処理オーバーヘッドにもかかわらず、貴重な高速メモリがほとんどないため、圧縮により実際にパフォーマンスが向上しました。テクスチャ座標、エッジの折り目、マテリアルの割り当てなどを含む100万ポリゴンメッシュに、約30メガバイトの空間インデックスを合わせることができるようになりました。
これは、800万個を超える四角形と、GF 8400(これは数年前のもの)を搭載したi3でのマルチ解像度サブディビジョンスキームを備えた可変プロトタイプです。不変バージョンよりも高速ですが、本番環境では使用しません。不変バージョンの方が保守がずっと簡単で、パフォーマンスへの影響もそれほど悪くないからです。ワイヤフレームはファセットを示すのではなく、パッチ(ワイヤは実際には曲線で、そうでない場合はメッシュ全体が黒一色になります)を示しますが、ファセット内のすべてのポイントはブラシによって変更されます。
とにかく、上記のいくつかを具体的な例と、メモリ管理が非常に役立つ領域を示したいと思っていました。メモリが豊富で安価であると人々が言うとき、私は少しイライラする傾向があります。それは、DRAMやハードドライブのような遅いメモリについて話しているからです。私たちが高速メモリについて話しているとき、それはまだとても小さくてとても貴重であり、本当に重要な(つまり、すべてではなく一般的なケース)パスのパフォーマンスは、その少量の高速メモリを再生し、できるだけ効果的にそれを利用することに関連します。
この種のことのために、たとえばC ++などの高レベルのオブジェクトを設計できる言語を使用しながら、これらのオブジェクトを1つまたは複数の連続した配列に格納でき、そのようなすべてのオブジェクトは、オブジェクトごとに不要なメモリオーバーヘッドなしで連続して表されます(例:すべてのオブジェクトがリフレクションまたは仮想ディスパッチを必要とするわけではありません)。これらのパフォーマンスが重要な領域に実際に移動すると、オブジェクトのオーバーヘッド、GCコストを回避し、頻繁にアクセスされるメモリを維持するために、オブジェクトプールをいじったり、プリミティブデータ型を使用したりするなど、メモリを制御することが生産性の向上になります一緒に隣接。
したがって、メモリ管理/制御(またはその欠如)は、実際には、どの言語が最も生産的に問題に取り組むことができるかを選択するための私の場合の支配的な理由です。私は間違いなく、パフォーマンスに重要ではないコードを共有します。そのために、Cから簡単に埋め込むことができるLuaを使用する傾向があります。