インテル® C++ コンパイラー 19.0 デベロッパー・ガイドおよびリファレンス
メモリーレイアウトへのアクセス方法を制御する列挙型です。#include <sdlt/access_by.h>
enum access_by
{
access_by_struct,
access_by_stride
};
access_by_struct は、構造体メンバーアクセスを介してデータにアクセスします。入れ子の構造体は、入れ子構造に従って構造体メンバーにアクセスします。例えば、2 つの Point3d オブジェクト (とデータメンバー x、y、z) を含む軸平行バウンディング・ボックス (AABB) は、次のように論理的に展開されます。
AABB local;
local = accessor.mData[i];
access_by_stride は、プリミティブのサイズを考慮したストライドで、ビルトイン型へのポインターを介してデータにアクセスします。2 つの Point3d オブジェクト (とデータメンバー x、y、z) を含む軸平行バウンディング・ボックス (AABB) は、次のように論理的に展開されます。
AABB local;
local.topLeft.x = *(accessor.mData + offsetof(AABB,topLeft) + offset(Point3d,x) + (sizeof(AABB)*i));
local.topLeft.y = *(accessor.mData + offsetof(AABB,topLeft) + offset(Point3d,y) + (sizeof(AABB)*i));
local.topLeft.z = *(accessor.mData + offsetof(AABB,topLeft) + offset(Point3d,z) + (sizeof(AABB)*i));
local.topRight.x = *(accessor.mData + offsetof(AABB,topRight) + offset(Point3d,x) + (sizeof(AABB)*i));
local.topRight.y = *(accessor.mData + offsetof(AABB,topRight) + offset(Point3d,y) + (sizeof(AABB)*i));
local.topRight.z = *(accessor.mData + offsetof(AABB,topRight) + offset(Point3d,z) + (sizeof(AABB)*i));
ベクトル化の際に、コンパイラーは幅の広いロードを実行し、シャッフル/挿入命令を使用してデータを SIMD レジスターに移動できるため、access_by_struc はより良いコードを生成できることがあります。ただし、プリミティブの複雑さによっては、特にプリミティブに入れ子の構造が含まれる場合など、ベクトル化に失敗することがあります。
一方、access_by_stride は、配列ポインターとストライドによる単純なデータアクセスのため、常にベクトル化されます。コンパイラーは、複雑さではなく、配列ポインターによるストライドアクセスのみを認識するため、どのような複雑さのプリミティブにも対応できます。
access_by_struct のほうが、特に SIMD ループ以外でより良いコードを生成できる可能性があるため、最適な選択肢と言えるでしょう。 ただし、ベクトル化で問題が生じた場合は、access_by_stride により問題が軽減されるかどうか試してみると良いでしょう。
どちらを選択するかは開発者次第ですが、明示的に選択する必要があります。