10

「パディングをオフにする方法は好きではありません」という形式の無数の質問を見てきましたが、コンパイラに追加のパディングを強制的に提供することについてはまだ何も見つけていません。

私が持っている特定のケースは次のようになります

struct particle{
  vect2 s;
  vect2 v;
  int rX;
  int rY;
  double mass;
  int boxNum;
};

単純vect2struct {double x; double y;} vect2. SSE2 を使用するには、16 バイト境界に揃えられた double のペアをロードできる必要があります。これは、extra を追加しintて構造体のサイズを 48 バイトから 56 バイトにプッシュするまで機能していました。その結果、セグメンテーション違反が発生します。

「この構造体を 16 バイトの倍数にするためにパディングする」または「この構造体は 16 バイトのアラインメントを持つ」というコンパイラ ディレクティブを使用できますか? 私は手動でそれを行うことができることを知っています(たとえば、追加のchar [12]を追加します)が、実際にはコンパイラ(GCC、できればICC互換)に伝えるだけで、手動で変更する必要はありません将来的に構造化します。

4

5 に答える 5

8

サイズを自分で追跡しなくても、2つの構造をネストして、自動的にパディングすることができます。

struct particle
{
    // ...
};

{
    particle p;
    char padding[16-(sizeof(particle)%16)];
};

構造がすでに16の倍数である場合、このバージョンでは残念ながら16バイトが追加されます。標準では長さがゼロの配列が許可されていないため、これは避けられません。

一部のコンパイラは、拡張として長さゼロの配列を許可します。その場合、代わりにこれを行うことができます。

struct particle_wrapper
{
    particle p;
    char padding[sizeof(particle)%16 ? 16-(sizeof(particle)%16) : 0];
};

このバージョンでは、構造がすでに16の倍数である場合、パディングのバイトは追加されません。

于 2012-06-22T17:01:14.603 に答える
6

ではgcc、任意の型と変数を に揃えることができます__attribute__((aligned(...)))。あなたの例では、これは

struct particle{
  vect2 s;
  vect2 v;
  int rX;
  int rY;
  double mass;
  int boxNum;
} __attribute__((aligned (16)));

これにより、構造体が自動的にパディングされ、その配列が正しく整列されます。

于 2012-06-23T18:28:33.107 に答える
1

新しいC++11仕様にもこのための新機能がありますが、まだ多くのベンダーが実装しているとは思いません。

仕様ではサポートされていませんが、パックプラグマを試すことができます。ただし、GCCとMSの両方がそれをサポートしています。

これにより、構造体が1バイト境界に揃えられますが、数値は任意に変更できます。

#pragma pack(push,1)
// ...
#pragma pack(pop)

アップデート:

したがって、上記はパディングを縮小するだけで、拡張することはないため、明らかに機能しません。残念ながら、今日の午後はテスト環境がありません。

たぶん匿名の組合を使うことはうまくいくでしょう。最大サイズに拡大することはわかっていますが、それ以外の場合は位置合わせについての保証が得られるかどうかはわかりません。

template<typename T, size_t padding_size>
  struct padded_field {
    union {
      T value;
      uint8_t padding[padding_size];
    };
  };
于 2012-06-22T16:46:16.810 に答える
1

テストされていませんが、これはうまくいくかもしれません:

#include <xmmintrin.h>

struct particle{
  union {
    vect2 s;
    __m128 s_for_alignment;
  };
  union {
    vect2 v;
    __m128 v_for_alignment;
  };
  ...
};

gcc には以前に正しく整列する問題があったことは知っています__m128が、これらは今では修正されているはずです。

于 2012-06-22T16:52:32.680 に答える