3

クラスを考えてみましょう:

template <typename T>
struct A{
  //...many public member functions...
  T x;
  T y;
  T z;
}

そして別の、同様:

template <typename T>
struct B{
  //many public member functions
  T x;
  T y;
}

ここでは指定されていませんが、T常にfloatまたはintまたはのいずれかになりますbool

ここで別の構造体を考えてみましょう:

struct Pair{
  A<float> a;
  B<float> b;
 }

vector

 std::vector<Pair> bigBunch;

xすべての, y, zinbigBunchが連続していると仮定するのはどのくらい安全ですか? vectors間の連続したメモリを保証することは知っていますが、パディングが発生する可能性があるため、必ずしも連続したメモリを保証するとは限らないPairことも知っています。ただし、パディングは、要素のタイプが異なるstruct場合にのみリスクになると思いました。struct

へのポインターを取得して、 のコンテンツ全体bigBunch[0].a.xで s の連続したストリームが期待できることを知りたいです。実際、へのポインターは、単に と言うのと同じ場所を指します。floatbigBunchbigBunch[0].a.x`bigBunch[0].a

Pair.aとが同じタイプであるか異なるタイプであるか (この例では両方が同じタイプであるのではなく、s をPair.b混合するなど) は問題になりますか?intfloatfloat

4

3 に答える 3

1

私の知る限り、標準には、コンパイラが良い考えだと判断した場合にパディングを追加することを妨げるものは何もありません。コンパイラには、この点でかなりの余裕があります。つまり、最善の方法は、たとえば 4 バイト境界での 4 バイト浮動小数点数によってパディングが発生してはならない場合でも、データをパックするように明示的にコンパイラに指示することです。

私の他の推奨事項はstatic_assert、すべてが必要なサイズであることを確認するために使用することです. 例えば、

template <typename T>
struct A{
  //...many public member functions...
  T x;
  T y;
  T z;
} __attribute__ ((__packed__));
static_assert(sizeof(A) == 3*sizeof(T), "struct A shouldn't be padded");

C++ 11 がない場合は、BOOST_STATIC_ASSERT代わりに使用できます。編集:__attribute__ ((__packed__))構造体の右中括弧の後のビットは、密集した構造体を確保するための GCC 固有の方法です。

vector<Pair>考慮する必要があるもう 1 つのことは、ギャップのない大きなfloat配列として扱うことができることから本当に利益が得られるかどうかです。すべてを反復する必要がある場合、または連続したデータを期待する他のライブラリにデータを渡す必要がある場合、一部のアルゴリズムを作成するのがより便利になる可能性があることを理解しています。struct Aしかし、これらの構造体を使って多くの計算を行っていると思います。たとえば、 128 ビットでアラインされている場合は SSE を使用して、コンパイラーがその一部を自動ベクトル化できる可能性があります。私の回答のこの部分には多くの当て推量がありますので、当てはまらない場合は無視してください。

PS: 構造体の右中括弧の後のセミコロンを忘れないでください。

于 2013-04-04T05:04:45.687 に答える
1

bigBunch のすべての x、y、z が連続していると想定するのは、どのくらい安全ですか?

安全ではありません。コンパイラにはパディングの自由があります。依存するT

bigBunch[0].ax へのポインターは、単に「bigBunch[0].a」と言うのと同じ場所を指します。

これは安全な仮定です。

両方が同じ型 (この例では float) ではなく、int と float が混在しているなど、Pair.a と Pair.b が同じ型か異なる型かは問題になりますか?

想定するのは安全ではありません。intとの場合float、私たちは幸運かもしれませんが、 と の場合はそうではないかもしれませshortint

パディング ストーリーは、32 ビット マシンと 64 ビット マシンの間で異なります。コードがすべてのアーキテクチャで機能するようにする場合、パディングとアラインメントについて仮定することはできません。

一般的な議論については、http://en.wikipedia.org/wiki/Data_structure_alignmentを参照してください。

要約すると、プログラムのパディングについて何も想定しないでください:-)

于 2013-04-04T05:28:57.607 に答える