C++ Cache友好的方式访问`vector <struct_type>`的所有元素的所有成员

Mat*_*son 5 c++ memory optimization struct cache-control

我有兴趣优化我的多线程计算代码.在缓存,流水线操作或内存访问的任何其他方面,如何比较保存这些资源:

情况1

struct something{
    float a;
    float b;
    int c;
    bool d;
};

vector <something> vec(n, something());

for(int q=0; q<n; q++)
    {
         vec[q].a = expression1;
         vec[q].b = expression2;
         vec[q].c = expression3;
         vec[q].d = expression4;
    } 
Run Code Online (Sandbox Code Playgroud)

案例2

struct something{
    float a;
    float b;
    int c;
    bool d;
};

vector <something> vec(n, something());

for(int q=0; q<n; q++)
    vec[q].a = expression1;
for(int q=0; q<n; q++)
    vec[q].b = expression2;
for(int q=0; q<n; q++)
    vec[q].c = expression3;
for(int q=0; q<n; q++)
    vec[q].d = expression4;
Run Code Online (Sandbox Code Playgroud)

案例3

vector <float> a(n);
vector <float> b(n);
vector <int>   c(n);
vector <bool>  d(n); 

for(int q=0; q<n; q++)
    a[q] = expression1;
for(int q=0; q<n; q++)
    b[q] = expression2;
for(int q=0; q<n; q++)
    c[q] = expression3;
for(int q=0; q<n; q++)
    d[q] = expression4;
Run Code Online (Sandbox Code Playgroud)

还有,有更好的方法来接近上述?

Mys*_*ial 3

  • 案例 1是最具可读性的。
  • 情况 1情况 3同样对缓存友好。两者仅一次遍历所有数据。*
  • 情况 2是最糟糕的,因为它对数据进行了 4 次传递 - 每一次仅接触一个元素。

如果所有结构体字段都不同,则情况 3具有可能可向量化的巨大优势,而情况 1则不然。

这样做的原因是因为情况 3数组打包结构,它将所有相同的数据类型在内存中按顺序放在一起 - 从而暴露矢量化。

编辑 :

*情况 3可能比情况 1更适合缓存,因为它不需要结构填充 - 因此数据大小更小。