2017-02-14 6 views
-1

私はC++:ベクトルとキャッシュ局所性のベクトルが

class Foo{ 
    std::vector<Foo*> myVec; 

    // Rest of the class 
}; 

int main(){ 
    // Some code 
    std::vector<Foo*> myVecOfFoo; 
} 

だから私のプログラムの中で経験していたキャッシュ・ミスのではなく、重要な数を軽減するライブラリ/ソリューションを探しています、私がした最初のものでしたstd::vector<Foo>を作成し、全てのFoo*がこのベクトルに向かって指し示すようにします。それは多くの助けとなりました。 私の主な問題はstd::vector<Foo*> myVec;です。これらのベクトルの内部配列のそれぞれは、メモリの異なる部分に配置されています。同じ方法で私はすべての私のFooがメモリ内で連続しているようにstd::vector<Foo>を作りました。私はすべて私のstd::vector<Foo*> myVec;をメモリ(実際には内部の配列)に揃えたいと思います。どうやって?

注:重要な点は、myVecのサイズがFooのインスタンスによって異なることです。そうでなければ、私は自明に単一のstd::vector<Foo*>を構築し、getters/setterを書くことができます。また、私は野蛮人ではないのでFoo*の代わりにstd::shared_ptr<Foo>を持っていますが、例の理解が容易になります。最後に、私は所有権がDAGを形成することを保証するので、私は共有ポインタにサイクルを持たない。

+0

まあ、可変サイジングでは、連続したメモリを取得するのが難しいかもしれません。それが重要なのであれば、私は多分アリーナ配分を調べるでしょう。 – mascoj

+0

私が考えることの1つは、すべてのデータを一緒にメモリに格納するカスタムアロケータを使用することです。しかし、あなたが持つことができる 'Foo'の数が制限されます。 – NathanOliver

+0

は、ブーストの[small_vector](http://www.boost.org/doc/libs/1_60_0/doc/html/boost/container/small_vector.html)を見てください – sp2danny

答えて

2

std::vector<Foo*>::const_iterator begin; 
std::vector<Foo*>::const_iterator end; 

一対のstd::vector<Foo*>を交換して、単一のstd::vector<Foo*>を作成し、そこにすべてのポインタを置きます。 beginendイテレータを設定して、Fooの個々のインスタンスへのポインタの連続したブロックを分割します。

「ノード」クラスのインスタンスからstd::vector<Foo*>というグラフを作成すると、前処理が必要になることがあります。

class FooNode { 
    Foo *myFoo; 
    std::vector<Foo*> myVec; 
}; 

あなたのノードが接続されると、グラフを歩くと、一つの大きなベクターにmyVec秒を収集します。すべての個々のベクトルが終了したら、再び予備グラフを歩き、beginendの位置をmyFooに設定します。現在の位置にFooNodeのベクトルのサイズを加えて位置を計算することができます。これは、グラフを通る散歩が同一である限り、機能します。

+0

私は本当にこの答えが好きでしたが、Francois Andrieuxは容量を超えてアイテムをstd :: vector で追加すると、すべてのイテレータは無効になります – Fezvez

+0

@Fezvez That's右!これは、前処理ステップが終了した後でも構造が静的にならなければならない理由です。 'FooNode'sからグラフを構築するための詳細を追加しました。これは、それ以上の変更が行われないことを確かめるまで、イテレータをベクターから取り除くことを延期します。 – dasblinkenlight

関連する問題