Intel® FPGA SDK for OpenCL™: ベスト・プラクティス・ガイド

ID 683521
日付 12/08/2017
Public
ドキュメント目次

3.5. 構造体をパディング付きまたはパディングなしで整列する

適切に整列された構造体は、 Intel® FPGA SDK for OpenCL™オフライン・コンパイラーが最も効率的なハードウェアを生成します。
適切なstructの整列とは、整列をstructのサイズで均等に分割することを意味します。
重要: データ構造の4バイト整列を確認してください。 structの整列が4バイトより小さいと、ハードウェアが大きくなり、遅くなります。整列の増加に伴い、ハードウェア効率が向上します。次の例では、 Pixel_s構造体は1バイトに整列していますが、 Pixel構造体は4バイトのnot_used整数が存在するために4バイト整列されています。
重要:
typedef struct {
	char r,g,b,alpha;
} Pixel_s;

typedef union {
     Pixel_s p;
     int not_used;
} Pixel;
また、次のコード例に示すように、 aligned属性を使用して4バイトのアラインメントを強制することもできます。
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™ プログラミング・ガイド