提供对AoS的AoS访问 [英] Provide AoS access to SoA

查看:102
本文介绍了提供对AoS的AoS访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将数据以数组结构(SoA)或指针结构(SoP)的形式布置在内存中,并且有一种访问该数据的方式,就好像它是以结构数组(AoS)的形式布置一样- -下面给出的代码.

I have data laid out in memory in a Structure of Arrays (SoA) or Sturcture of Pointers (SoP) form, and have a way to access that data as though it were laid out in Array of Structure (AoS) form -- code given below.

但是,我对使用struct AoS_4_SoP不太满意-尽管此struct似乎使用模板,但它并不是通用的,因为例如foobar在内部进行了硬编码它.

However, I am not too happy about use of struct AoS_4_SoP -- although this struct appears to use templates, it is not really generic since, for example, foo and bar are hard-coded inside it.

1)为了实现读写性能,AoS访问是否与直接SoA访问一样好?

1) For read-write performance, is AoS access provided as good as the direct SoA access?

2)什么是更通用的方案? (我见过 quamrana 在这里编码,但没有帮助.)

2) What would a more generic scheme be? (I have seen quamrana's code here, but it hasn't helped.)

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(),显示了上面的用法:

Here's a main() showing the use of the above:

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;
}

以上代码可以通过以下方式进行编译:

Above code can be compiled via:

// 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

推荐答案

我认为此模板可以工作.

I think this template will work.

template<class T, class U, class D, class S>
struct Accessor {
    T* p;
    U* (T::*pFirst);
    D* (T::*pSecond);
    S operator[](size_t index) {
        return {(p->*pFirst)[index], (p->*pSecond)[index]};
    }
    Accessor(T* p_, U * (T::*pF), D * (T::*pS)): p(p_), pFirst(pF), pSecond(pS) {}
};

void 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());

    Accessor<SoP, int, double, SoR> aos(&x_sop, &SoP::foo, &SoP::bar);

    aos[0].foo;
}

现在,模板访问器对T的成员名称一无所知.

Now the template Accessor knows nothing about the names of the members of T.

至少它是在VS2015下编译的

At least it compiles under VS2015

这篇关于提供对AoS的AoS访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆