我已经看过几次 Mike Acton 关于 DOD 的演讲,以便更好地理解它(这对我来说不是一个容易的话题)。我指的是 CppCon 2014: Mike Acton "Data-Oriented Design and C++" 和GDC 2015: How to Write Code the Compiler Can 实际上 Optimize。
这表明FooUpdateIn占用 12 个字节,但如果您堆叠其中的 32 个字节,您将获得 6 个完全打包的缓存行。FooUpdateOut也是如此,它需要 4 个字节,其中 32 个字节为您提供 2 个完全打包的缓存行。
在UpdateFoos函数中,您可以为每个高速缓存行执行约 5.33 个循环(假设计数确实为 32),然后他继续假设完成的所有数学运算大约需要 40 个周期,这意味着每个高速缓存行将需要大约 213.33 个周期。
现在这就是我感到困惑的地方,他不是忘记了读写吗?尽管他有 2 个完全打包的数据结构,但它们位于不同的内存空间中。在我的脑海里,这就是正在发生的事情:
- 读入[0].m_Velocity[0](根据他之前的幻灯片,这需要大约 200 个周期)
- 由于in[0].m_Velocity[1]和in[0].m_Foo与 in[0].m_Velocity[0]位于同一缓存行中,因此它们的访问是免费的
- 做所有的计算
- 将结果写入out[0].m_Foo - 这是我不知道会发生什么,我假设它会丢弃前一个缓存行(在 1 中获取)并加载新的缓存行以写入结果
- 读入[1].m_Velocity[0],这将再次丢弃另一个缓存行(在 4 中获取)(这将再次花费大约 200 个周期)
- ...
因此,从进出跳出,计算从~ 5.33 循环/缓存行变为0.5 个循环/缓存行,每个缓存行执行 20 个周期。
有人可以解释为什么他不关心读/写吗?或者我的想法有什么问题?
谢谢你。