C++:具有函数的缓存友好性

C++: cache-friendliness with functors

本文关键字:缓存 函数 C++      更新时间:2023-10-16

我正在C++中制作一个简短的(但在CPU/GPU使用方面很昂贵)粒子系统库,其中需要性能和模块性。我希望用户能够制作自己的函子,并将其传递给update()函数,从而准确地确定给定集合的粒子在每帧中的演化方式(一个函子用于颜色、比例、位置…)

这需要通过引用或指针将函子传递给函数update()(作为抽象类参数),这意味着每当我在一个粒子上调用函子时,我的程序(如果我错了,请纠正我,我不确定我对缓存层的理解是否正确)在从函子加载数据时会生成缓存未命中,然后当我想迭代该集合的下一个粒子时,重新生成缓存未命中。

这听起来像是对CPU时间的巨大浪费。我怎么能绕过它?我对这个问题的理解正确吗?有什么问题吗?

有什么问题吗?

没有测量很难判断。引用和指针等间接操作有可能损害性能,这一点是正确的。在您的特定程序中是否存在这种情况,必须通过测量来确定。

问题的一个常用解决方案是接受函子作为模板参数,如下所示:

template <class Functor>
void update (Functor f){...}

这样,函数甚至可以进行内联。

衡量这类事情的性能影响很重要。

根据CPU的不同,这可能很昂贵或几乎是免费的。很抱歉,我不知道细节,但我知道我在自己的经历中看到过同一代码的不同配置文件。

我相信大多数现代CPU都会缓存指针,并通过其间接分支进行推测,就像处理函数调用返回一样。

然而,这里最好的C++技术是将函数制作成一个模板,该模板可以接受看起来像函数调用的任何类型的参数。

这样,编译器就可以将函子内联到函数中,从而消除任何可能的惩罚。