配列の構造 (SoA) またはポインターの構造 (SoP) 形式でメモリ内に配置されたデータがあり、構造の配列 (AoS) 形式で配置されているかのようにそのデータにアクセスする方法があります。下。
ただし、の使用についてはあまり満足していません。struct AoS_4_SoP
これstruct
はテンプレートを使用しているように見えますが、たとえばが内部にハードコーディングされているfoo
ため、実際には一般的ではありません。bar
2 つの質問/リクエスト:
1) 読み書きのパフォーマンスに関して、AoS アクセスは直接 SoA アクセスと同じくらい良好に提供されていますか?
2) より一般的なスキームは何でしょうか? (私はquamranaのコードをここで見ましたが、役に立ちませんでした。)
struct SoP{ // Structure of Pointers
int *foo{ nullptr };
double *bar{ nullptr };
SoP( int *xi, double *xd ):foo(xi), bar(xd){};
};
struct SoR{ // Structure of References
int &foo;
double &bar;
SoR( int &xi, double &xd ):foo(xi), bar(xd){};
};
template< typename T, typename S >
struct AoS_4_SoP {
AoS_4_SoP( T *x ) : p( x ){};
T *p;
S operator[](std::size_t idx) const { return { p->foo[idx], p->bar[idx] }; }
const S operator[](std::size_t idx) const { return { p->foo[idx], p->bar[idx] }; }
};
上記のmain()
使用例を次に示します。
int main()
{
std::vector< int > ibuf{ 11, 22, 33, 44 };
std::vector< double > dbuf{ 0.11, 0.22, 0.33, 0.44 };;
SoP x_sop( ibuf.data(), dbuf.data() );
ibuf.at(2) = 333;
std::cout << "Access via SoP syntax:\n "
<< x_sop.foo[2]
<< " "
<< x_sop.bar[2] << std::endl;
AoS_4_SoP<SoP, SoR> xacc( &x_sop );
std::cout << "Access via AoS syntax:\n "
<< xacc[2].foo
<< " "
<< xacc[2].bar << std::endl;
// show write access via SoA syntax
ibuf.at(2) = 3333;
dbuf.at( 2 ) = 0.333333; // will get overwritten below
xacc[2].bar = 0.3333;
std::cout << "Values written via SoP, read via SoP:\n "
<< x_sop.foo[2]
<< " "
<< x_sop.bar[2] << std::endl;
// show write access via AoS syntax
xacc[2].foo = 333333;
dbuf.at( 2 ) = 0.3333333333; // will get overwritten below
xacc[2].bar = 0.333333;
std::cout << "Values written via AoS, read via AoS:\n "
<< xacc[2].foo
<< " "
<< xacc[2].bar << std::endl;
}
上記のコードは、次の方法でコンパイルできます。
// x86_64-w64-mingw32-g++.exe -D_WIN64 -Wall -Wextra -Werror -std=c++11 -O3 -static-libgcc -static-libstdc++ aossoa.cc -o aossoa.exe
次の出力が得られます。
Access via SoP syntax:
333 0.33
Access via AoS syntax:
333 0.33
Values written via SoP, read via SoP:
3333 0.3333
Values written via AoS, read via AoS:
333333 0.333333