【发布时间】:2024-04-17 12:30:01
【问题描述】:
我想学习如何编写更好的代码来利用 CPU 的缓存。使用连续内存似乎是理想的情况。话虽如此,我很好奇是否可以使用非连续内存进行类似的改进,但要遵循一组指针,例如:
struct Position {
int32_t x,y,z;
}
...
std::vector<Position*> posPointers;
...
updatePosition () {
for (uint32_t i = 0; i < posPointers.size(); i++) {
Position& nextPos = *posPointers[i];
nextPos.x++;
nextPos.y++;
nextPos.z++;
}
}
这只是一些粗略的模拟代码,为了正确学习,我们假设所有 Position 结构都是在整个堆中随机创建的。
英特尔 i7 等现代智能处理器能否展望未来并发现它很快就会需要X_ptr 的数据?以下代码行会有帮助吗?
... // for loop
Position& nextPos1 = *posPointers[i];
Position& nextPos2 = *posPointers[i+1];
Position& nextPos3 = *posPointers[i+2];
Position& nextPos4 = *posPointers[i+3];
... // Work on data here
我读过一些演示幻灯片,这些幻灯片似乎表明这样的代码会导致处理器预取一些数据。真的吗?我知道有一些非标准的、特定于平台的方法来调用像__builtin_prefetch 这样的预取,但是到处乱扔它似乎是一个丑陋的过早优化。我正在寻找一种可以下意识地编写高效缓存代码的方法。
【问题讨论】:
-
这样的代码不太可能表现良好,它对缓存非常不友好,并且不会自动矢量化。简单的解决方法是
std::vector<Position>,复制一份。 -
创建该副本同样会导致缓存效率低下。您仍然需要从所有内存中收集对象。如果结果需要存储回来,制作副本会更糟糕。
标签: c++ performance caching pointers cpu-cache