10

私はソフトウェアの速度を上げるためにOpenCLを試しています。私たちはマップを頻繁に扱い、単純化するために、マップをstd :: vector <std::vector>として表します。OpenCL APIは、生のcスタイルのポインターを引数として受け取ります。たとえば、上記の場合はint*です。

私の質問:

  • ベクトルが内部的にメモリ内で連続しているという実装保証がstlにありますか?
  • std ::vectorをint*に安全にキャストして、それが機能することを期待できますか?
  • ベクトルのベクトルの場合でも、これが当てはまると仮定できますか?ベクトルが他の状態データ、アライメントの問題、またはおそらく他の何かを保持することを期待します...
  • これに取り組むための最良の方法は何ですか?内部の連続したメモリ内バッファを保持するカスタム2Dデータ構造を記述し、それを処理しますか?ベクトルとの間でたくさんコピーする必要があります...

ありがとう。

4

4 に答える 4

18

ベクトルが内部的にメモリ内で連続しているという実装保証がstlにありますか?

C ++ 03の時点では、はい、ベクターは連続したストレージを使用することが保証されています。(C ++ 98では、偶発的な抜け穴があったため、実装は仮想的に非連続ストレージを使用できましたが、2003年の改訂版で修正されました。実際には、非連続ストレージを使用する実装はありませんでした。ひどい考え)

std ::vectorをint*に安全にキャストして、それが機能することを期待できますか?

通常の方法は&v[0]です。(&*v.begin()おそらくうまくいくでしょうが、これを100%信頼できないものにする標準にいくつかのふわふわした言葉遣いがあることを思い出しているようです)

いいえ。なぜそれが機能すると期待するのですか?ベクトルはクラスです。ポインタではありません。ポインタが含まれているだけです。

ベクトルのベクトルの場合でも、これが当てはまると仮定できますか?ベクトルが他の状態データ、アライメントの問題、またはおそらく他の何かを保持することを期待します...

ベクトルは、格納するものと同じように動作します。ベクトルのベクトルを作成すると、ヒープに割り当てられた配列へのポインターを含むオブジェクトになります。各要素は、ヒープに割り当てられた配列へのポインターを含むオブジェクトです。

これにどのように取り組むべきかについては、多くの要因に依存します。データセット全体の大きさはどれくらいですか?テーブル全体を連続して割り当てることができます。ベクトルのベクトルでは、各行は個別の割り当てです。

于 2009-09-07T10:23:32.533 に答える
5

  • ベクトルが内部的にメモリ内で連続しているという実装保証がstlにありますか

はい、それは動的配列です。標準では、ベクトル内のオブジェクトが連続して格納されることが保証されています。

  • std ::vectorをint*に安全にキャストして、それが機能することを期待できますか?

いいえ。ただし、begin()を使用して、それをポインターとして使用できます。


  • ベクトルが内部的にメモリ内で連続しているという実装保証がstlにありますか

いいえ、ベクトルにはいくつかの内部メンバー変数が含まれている可能性があるため、2D配列全体が連続したメモリ位置にはなりません

于 2009-09-07T10:29:31.693 に答える
4

ベクトルが内部的にメモリ内で連続しているという実装保証がstlにありますか?

ここで標準を引用することはできませんが、このレイアウト(つまり、POCO)を想定した高品質のライブラリのコードを見てきました。

std ::vectorをint*に安全にキャストして、それが機能することを期待できますか?

具体的には、ベクトル自体を再キャストすることはできません。しかし、私は次のコードを見ました:

std::vector<int> vec;
int* ptr = &vec[0];

ベクトルのベクトルの場合でも、これが当てはまると仮定できますか?ベクトルが他の状態データ、アライメントの問題、またはおそらく他の何かを保持することを期待します...

おそらく、ベクトルのベクトルを線形配列にキャストすることはできません。各ベクトルは独自のメモリ範囲を予約し、これらの範囲のすべてがシーケンシャルであると期待することはできません。

于 2009-09-07T10:21:24.317 に答える
3

コメントで、最大2500x2500xsizeof(double)データを処理すると述べました。その場合、ベクトルのベクトルの代わりに単一のベクトルを使用することをお勧めします。必要に応じて、NxM要素をベクトルに割り当て、2次元のインデックスを公開するクラスにラップします。最小限のオーバーヘッドでベクトルのすべての利点を享受し、すべてのデータは高速処理のために連続したメモリに残ります。

于 2009-09-07T19:56:43.367 に答える