インテルのみ表示可能 — GUID: ewa1417026580901
Ixiasoft
3.5. 構造体をパディング付きまたはパディングなしで整列する
typedef struct {
char r,g,b,alpha;
} Pixel_s;
typedef union {
Pixel_s p;
int not_used;
} Pixel;
typedef struct {char r、g、b、alpha; } __attribute __((aligned(4)))ピクセル;
オフライン・コンパイラーは、次のすべての基準を満たすために構造体のアラインメントを必要とするISO C標準に準拠しています。
- アラインメントは、すべての構造体メンバーのアラインメント間の最小公倍数の整数倍でなければなりません。
- このマクロの値は、2の累乗である必要があります。
カーネルコードにaligned( N )属性を含めることで、 structの整列を設定することができます。整列属性なしで、オフライン・コンパイラーは、 structのサイズに基づいて、 structのアレイ内の各structのアラインメントを決定します。次の例を検討してください。
__kernel void test (struct mystruct* A,
struct mystruct* B)
{
A[get_global_id(0)] = B[get_global_id(0)];
}
mystructのサイズが101バイトの場合、各ロードまたはストアのアクセスは1バイトで整列されます。 mystructのサイズが128バイトの場合、各ロードまたはストアのアクセスは128バイトに整列され、最も効率的なハードウェアが生成されます。
構造体のフィールドは、structの中に整列されていない場合、オフラインのコンパイラーはそれらを整列するためにパディングを挿入します。 structフィールド間にパディングを挿入すると、次のようにハードウェアの効率に影響します。
- 構造体のサイズを増やす
- アラインメントに影響する可能性がある
オフライン・コンパイラーがパディングを挿入しないようにするには、カーネルコードにpacked属性を含めます。前述のISO C標準は、パックされたstructまたはアンパックされたstructのアラインメントを決定するときに適用されます。次の例を検討してください。
struct mystruct1
{
char a;
int b;
};
mystruct1のサイズは8バイトです。したがって、 structは8バイトに整列され、カーネル内で効率的にアクセスされます。ここで別の例を検討してください。
struct mystruct2
{
char a;
int b;
int c;
};
mystruct2のサイズは12バイトで、 structは4バイトに整列しています。structフィールドはパディングされており、structはアラインメントされていないため、カーネル内のアクセスは非効率的です。
以下にpacked属性を含むstructの例を示します。
struct __attribute__((packed)) mystruct3
{
char a;
int b;
int c;
};
mystruct4のサイズは16バイトです。 mystruct4が整列され、 structフィールドの間にパディングがないため、このカーネルのアクセスはmystruct3のアクセスよりも効率的です 。
構造体にaligned( N )属性とpacked属性の両方を含めるには、次の例を考えてください。
struct __attribute__((packed)) __attribute__((aligned(16))) mystruct5
{
char a;
int b;
int c;
};
mystruct5のサイズは9バイトです。 aligned(16)属性のため、 structは配列内の16バイト整列アドレスに格納されます。 mystruct5は16バイトで整列されており、パディングもないため、このカーネルでのアクセスは効率的です。
structの整列とaligned( N )およびpacked属性の詳細については、以下の文書を参照してください。
- OpenCL仕様バージョン1.2.1のセクション6.11.1
- インテル® FPGA SDK for OpenCL™ プログラミング・ガイドのデータ構造の挿入のディセーブル
- Structアラインメントの指定のセクションの インテル® FPGA SDK for OpenCL™ プログラミング・ガイド