c++ - 如何在 Windows 上将 std::vector 固定/取消固定到实际的、未压缩的硬件内存?
问题描述
背景
我正在研究一些科学数据处理管道。它是高度并行化和性能优化的——问题是在使用大量内存的管道中,CPU 使用率下降到 10% 以下,尽管它是并行化的并且不包含关键部分(实际上每个 CPU 都会低于10% 工作负载状态)。
在处理的这一点上,文件系统上的文件没有显式访问(写入或读取)。该应用程序显示为已提交 94GB 和 6.5GB 工作集(我不确定在 Windows 上工作集是否包含压缩内存)。
它还显示 0 Hard Faults/sec,但我看不出在完全并行化的代码执行期间 CPU 使用率低于 10% 的其他原因,没有关键部分和磁盘 I/O,如果它与任何一个分页都不相关的话或内存压缩/解压缩。
代码
现在,简化后,我的数据结构和算法看起来像这样:
struct Tile {
struct Datapoint {
float pos[3];
float uv[2];
float col[4];
};
struct Cluster {
std::vector<size_t> indices;
std::vector<float> weights;
};
std::vector<Datapoint> datapoints;
std::vector<Cluster> clusters;
};
std::vector<Tile> tiles;
FillTiles(tiles); // this is not slow and is generating the ~100GB of data in memory
std::vector<float> filtered_data(tiles.size());
// the following is slow
ParallelFor(thread_count, tiles.size(), [&](int i) {
filtered_data[i] = FilterTile(tiles[i]);
});
我正在使用的 ParallelFor 在我的其他代码中运行良好,并且该float FilterTile(const Tile& tile)
函数没有关键部分,因此它仅适用于 Tile 的数据(但此处粘贴太复杂)。
我现在想做的是这样的:
ParallelFor(thread_count, tiles.size(), [&](int i) {
Pin(tiles[i+100]); // pseudocode, obviously propper bound checking has to be done.
filtered_data[i] = FilterTile(tiles[i]);
Unpin(tiles[i]);
});
需要void Pin(const Tile& tile)
做的是告诉 Windows 它应该将与此磁贴关联的数据移动到未压缩的主内存中,并将其保留在那里,直到我调用void Unpin(const Tile& tile)
.
问题
如何请求将数据固定
std::vector<Datapoint> datapoints
到未压缩的主内存而不阻塞?我现在正在寻找可以在 Windows 10 上运行的东西,并且不一定需要一种便携的方式来做到这一点。虽然
std::vector<Datapoint> datapoints
只包含一块连续内存,但其中的元素std::vector<Cluster> clusters
包含我想要预取和固定的 std::vectors 本身。我不认为有一些开箱即用的递归解决方案,所以 - 如果有第一个问题的解决方案(我绝对肯定有,因为例如 OpenGL 驱动程序也可以这样做) - 是否有某种订阅回调的方式,以便我可以std::vector<Cluster> clusters
在完全固定时收到通知,以便我可以遍历它以请求固定每个集群元素std::vector<size_t> indices
和std::vector<float> weights
每个集群元素?执行情况如何
void Unpin(const Tile& tile)
?额外问题:我在 Xeon Gold CPU 上运行,每个内核具有 1MB 的二级缓存。大多数图块只有几百 KB。所以我想知道除此之外
Pin(tiles[i+100]);
我是否还可以实现MoveToL2(tiles[i+1]);
将下一次迭代的数据预取到 L2 内存中。如果是这样,我该如何实施?
解决方案
推荐阅读
- postgresql - 连接到通过 docker 在我的 ubuntu 服务器上运行的 postgres 实例
- javascript - [Vue 警告]:v-on 处理程序中的错误:“TypeError:fs.existsSync 不是函数”
- pythonanywhere - 这就是我必须为自定义域做的所有事情吗?
- mysql - 我想检查上面的值是否重复。我该怎么做?
- microsoft-translator - Microsoft 翻译器更改有 html 跨度的短语
- python - 如何显示类别名称和描述?
- c# - 错误!'对象不能从 DBNull 转换为其他类型。' C# 使用方法 sum()
- python - 如何在 Dask 任务执行之间保留一些 Python 对象状态?
- c - filename_lookup 在 4.18 的 RHEL 8 中不可用,替代方案是什么?
- mkmapview - 在 SwiftUI 中为 MKMapView 添加“显示用户位置”按钮的正确方法是什么?