1

構造体の配列を引数としてカーネルに渡すと、最初の項目 (array[1]、array[2] など) の後に奇妙な値が得られます。多分アライメントの問題のようですか?

構造体は次のとおりです。

typedef struct Sphere
{
    float3 color;
    float3 position;
    float3 reflectivity;
    float radius;
    int phong;
    bool isReflective;
} Sphere;

ホスト側の初期化コードは次のとおりです。

cl::Buffer cl_spheres = cl::Buffer(context, CL_MEM_READ_ONLY, sizeof(Sphere) * MAX_SPHERES, NULL, &err);
err = queue.enqueueWriteBuffer(cl_spheres, CL_TRUE, 0, sizeof(Sphere) * MAX_SPHERES, spheres, NULL, &event);
err = kernel.setArg(3, cl_spheres);

何が起こるかというと、配列内の 2 番目の Sphere 構造体の色は、実際には、ホスト側 (s3 または z) で色を設定した最後の値、初期化されていないゼロの値、および設定したものの最初の値を持つことになります。ホスト側 (s0 または x) に配置します。float3 データ型には、実際にはまだ初期化されていない 4 番目の値 (s3) があることに気付きました。初期化されていないゼロ値の由来はそこにあると思います。したがって、それはアライメントの問題のようです。私はそれを修正するために何ができるかについて本当に途方に暮れています。誰かがこの問題に光を当てることができるかもしれないと思っていました。構造体の定義が両側でまったく同じであることを確認しました。

4

1 に答える 1

1

OpenCL 1.2 仕様のセクション 6.11.1 から:

任意の構造体または共用体型のアラインメントは、ISO C 標準によって、問題の構造体または共用体のすべてのメンバーのアラインメントの最小公倍数の少なくとも完全な倍数であることが要求されており、また、 2 のべき乗。

としてもcl_float3カウントされcl_float4ます。セクション 6.1.5 を参照してください。

最後に、セクション 6.9.k で:

プログラム内のカーネル関数への引数は、組み込みスカラー型 bool、half、size_t、ptrdiff_t、intptr_t、および uintptr_t、またはこれらの組み込みスカラー型の 1 つであると宣言されたフィールドを含む構造体および/または共用体で宣言することはできません。 .

これらのルールに準拠し、おそらくアクセスを高速化するには、次を試すことができます (OpenCL C 側; ホストでは を使用cl_float4):

typedef struct Sphere
{
    float4 color;
    float4 position;
    float4 reflectivity;
    float4 radiusPhongReflective; // each value uses 1 float
} Sphere;
于 2012-04-16T20:20:51.553 に答える