OOP中的数据导向设计

Tia*_*sta 7 c++ data-oriented-design

在这张幻灯片中 (幻灯片15之后)建议使用

void updateAims(float* aimDir, const AimingData* aim, vec3 target, uint count)
{
     for(uint i = 0; i < count; i++)
     {
          aimDir[i] = dot3(aim->positions[i], target) * aim->mod[i];
     }
}
Run Code Online (Sandbox Code Playgroud)

因为它的缓存效率更高.

如果我上课怎么样?

class Bot
{
    vec3 position;
    float mod;
    float aimDir;

    void UpdateAim(vec3 target)
    {
         aimDir = dot3(position, target) * mod;
    }
 };

 void updateBots(Bots* pBots, uint count, vec3 target)
 {
      for(uint i = 0; i < count; i++)
            pBots[i]->UpdateAim(target);
  }
Run Code Online (Sandbox Code Playgroud)

我将该类的所有对象存储在一个线性数组中.

因为它们都在同一个数组中会有缓存未命中吗?为什么第一种方法会更好?

Mik*_*our 11

现代缓存架构通常被构造为数据线,每个数据块足够大以容纳几个字; 64字节是典型的行大小.当您尝试读取不在缓存中的数据时,将获取整行,而不仅仅是您需要的单词.写入时,如果缓存中的数据存在,则会更新缓存中的数据,但如果不存在则通常不需要获取.

在第一种情况下,对于每个获取的输入数据的高速缓存行,您将使用它的每个单词.在第二个,你只会使用一些结构字段; 抓住其他人浪费了一些带宽.

具体来说,您将获取aimDir每次的旧值,这是计算所不需要的.通常,"对象"可能包含更多字段,您不希望进行此特定计算,因为它们被提取到缓存中然后被忽略,会浪费更多带宽.