【发布时间】:2018-10-31 18:45:29
【问题描述】:
我知道,当对容器的每个元素进行一些计算时,如果内存是连续的,则可以获得最佳性能。 但是,如果必须同时处理两个或多个大容器(这样它们就不能完全适应缓存)怎么办?
int main()
{
const std::size_t BIG_SIZE = 2000000; // A number such that both ivec and fvec won't fit the cache
std::vector<int> ivec(BIG_SIZE, 0);
int start = 0;
for (auto& i : ivec)
i = start++;
std::vector<float> fvec(BIG_SIZE, 0.f);
auto iit = ivec.cbegin();
auto fit = fvec.begin();
for (; iit != ivec.cend() && fit != fvec.end(); ++iit, ++fit)
*fit = *iit * 3.14; // What happens here?
}
在最后一个循环中,缓存会同时加载*iit 附近的内存块和*fit 附近的内存块,还是每次访问*iit 和*fit 时都会错过缓存?
如果是后者,我是否应该以交错模式自定义分配 ivec 和 fvec 以防止这些失误?
【问题讨论】:
-
有几个缓存行。
-
在某个级别上,这一切都非常简单——每次你从内存中读取时,CPU 预取(和后取)比你实际读取的多——整个缓存行都被获取了。但是 CPU 中存在不止一个缓存行,因此从不同内存地址读取应该填充不同的缓存行。我不希望您受到这种模式的惩罚,但使用专门的工具进行验证总是值得的。
-
很大程度上取决于您使用的 什么 CPU 以及它的内存/缓存层次结构是什么样的(有些根本没有缓存,也存在 NUMA 架构)。不同的 CPU 也有不同的预取机制和不同的缓存驱逐策略。没有“一个真正的答案”,这完全取决于所讨论的硬件。
-
哪个 CPU?它是非常特定于 CPU 的。
-
一个典型的高速缓存行是 64 字节,这将提供一个 32KB 的一级高速缓存 512 个高速缓存行
标签: c++ memory-management cpu-cache