これらは小さく自己完結型のオブジェクトです。ポインターを置くのではなく、直接キューに入れます。実際に
- 、64ビットシステムでと
int
を仮定は、ポインタがオブジェクト自体と同じ大きさであろう(それはたとえば、Visual C++の下で、である)、32ビットであります!したがって、バルクアロケータを持っていても、この価格を支払うことになります。
- 一般的なメモリアロケータは時間的に高価なだけでなく、オブジェクトごとのオーバーヘッドを持ちます。この場合、オブジェクト自体が矮小になります(バルクアロケータには適用されません)。
あなたはかなり効率的な「バルク」割り当て方式を考案できますが、私はそれが問題を回避し、完全に個々のオブジェクトの割り当てを回避するために簡単だと思います。
--- EDITは---あなたがこのようなstd::queue
に要素をプッシュすることができ
:std::priority_queue
について
struct grid_cell {
grid_cell(int x0, int y0) {
x=x0;
y=y0;
}
int x;
int y;
};
// ...
std::queue<grid_cell> q;
q.push(grid_cell(0, 0));
q.push(grid_cell(0, 1));
q.push(grid_cell(0, 2));
q.push(grid_cell(1, 0));
q.push(grid_cell(1, 1));
q.push(grid_cell(1, 2));
、あなたはためにあなたがしたい方法を決定する必要があるだろうの要素。あなたのコード@Richard
--- EDIT 2 ---
はかなり異なっています。
push
ごとに、コードはダイナミックメモリの新しいブロックを割り当てます。x
とy
を割り当て)、ポインタをそのメモリブロックにキューに押します。
- 私のコードは、
queue
によってあらかじめ割り当てられた大きなメモリブロック内の "スロット"にオブジェクトを直接構築します。すでに述べたように、小さな割り当てよりも多くの割り当てが少ないのは、 です。
あなたのコードです:メモリを起こしやすい
- は
- をリークしますが、オブジェクトごとのオーバーヘッドがあるメモリの断片化が発生しやすい
- と
- 、ポインタのための余分なストレージのために支払います、すでに述べたとおりです。
特殊なバルクアロケータは、最後の2つの問題を削除できますが、それらをすべて削除しないのはなぜですか?
--- EDIT 3 ---速度として
、一般的な動的メモリ割り当ては、高価(最良アロケータ約40~50マシン命令)です。
特殊なブロックアロケータははるかに高速ですが、メモリレイテンシの問題があります。すべてをうまくまとめておくと、キャッシュのローカリティが向上し、CPUのプリフェッチロジックに適しています。キューと実際のオブジェクトを参照しないでください。
ポインタを押す必要がありますか?値をプッシュして、ダイナミックメモリを自分で割り当てることによるトラブルやスピードの影響を抑えることができます。 –
いいえ、ポインタは、新しい 'grid_cell'インスタンスをこのようなやり方でキューに入れる方法がわからないからです。 – Richard
@リチャード:ちょうどこれをしてください: 'my_queue.push(grid_cell(x0、y0));' –