数组的结构和结构的数组

我有这样的课程:

//Array of Structures
class Unit
{
  public:
    float v;
    float u;
    //And similarly many other variables of float type, upto 10-12 of them.
    void update()
    {
       v+=u;
       v=v*i*t;
       //And many other equations
    }
};

我创建了Unit类型的对象数组。 并致电更新。

int NUM_UNITS = 10000;
void ProcessUpdate()
{
  Unit *units = new Unit[NUM_UNITS];
  for(int i = 0; i < NUM_UNITS; i++)
  {
    units[i].update();
  }
}

为了加快速度,并可能自动化循环,我将AoS转换为数组结构。

//Structure of Arrays:
class Unit
{
  public:
  Unit(int NUM_UNITS)
  {
    v = new float[NUM_UNITS];
  }
  float *v;
  float *u;
  //Mnay other variables
  void update()
  {
    for(int i = 0; i < NUM_UNITS; i++)
    {
      v[i]+=u[i];
      //Many other equations
    }
  }
};

当循环失败autoloctorize,我得到一个非常糟糕的性能数组结构。 对于50个单位,SoA的更新比AoS稍快。但从100个单位开始,SoA比AoS慢。 在300台机组中,SoA差不多是它的两倍。 在100K单位,SoA比AoS慢4倍。 虽然缓存可能是SoA的一个问题,但我并没有预料到性能差异会如此之高。 对cachegrind进行性能分析,显示两种方法的缺失数量相似。 Unit对象的大小是48个字节。 L1缓存为256K,L2为1MB,L3为8MB。 我在这里错过了什么? 这真的是缓存问题吗?

编辑:我正在使用gcc 4.5.2。 编译器选项是-o3 -msse4 -ftree-vectorize。

我在SoA做了另一个实验。 我没有动态分配数组,而是在编译时分配了“v”和“u”。 当有100K个单元时,这个性能比具有动态分配阵列的SoA快10倍。 这里发生了什么事? 为什么静态和动态分配内存之间存在性能差异?


在这种情况下,数组的结构不是缓存友好的。

你同时使用uv ,但是如果有两个不同的数组,它们将不会被同时加载到一个缓存行中,并且缓存未命中会造成巨大的性能损失。

_mm_prefetch可以用来使AoS表示更快。


预取对于花费其大部分执行时间等待数据显示的代码至关重要。 现代前端总线有足够的带宽,预取应该是安全的,只要你的程序没有超出当前负载的范围。

由于各种原因,结构和类可能会在C ++中创建大量性能问题,并且可能需要更多调整才能获得可接受的性能水平。 当代码很大时,使用面向对象的编程。 当数据很大(并且性能很重要)时,不要。

float v[N];
float u[N];
    //And similarly many other variables of float type, up to 10-12 of them.
//Either using an inlined function or just adding this text in main()
       v[j] += u[j];
       v[j] = v[j] * i[j] * t[j];

当然,如果你没有实现向量化,那么没有太多的动机来进行SoA转换。

除了__RESTRICT的相当广泛的事实认可外,gcc 4.9已采用#pragma GCC ivdep来打破假定的别名依赖关系。

至于使用显式预取,如果它是有用的,当然你可能需要更多的SoA。 主要的观点可能是通过提前提取页面来加速DTLB未命中的解决方案,因此您的算法可能会变得更加缓慢。

我不认为任何你称之为“编译时”分配的智能评论可能没有更多细节,包括关于你的操作系统的细节。 毫无疑问,高水平分配和重新使用分配的传统非常重要。

链接地址: http://www.djcxy.com/p/85531.html

上一篇: Structure of arrays and array of structures

下一篇: C code loop performance [continued]