首页 > 解决方案 > 如何在 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).

问题

  1. 如何请求将数据固定std::vector<Datapoint> datapoints到未压缩的主内存而不阻塞?我现在正在寻找可以在 Windows 10 上运行的东西,并且不一定需要一种便携的方式来做到这一点。

  2. 虽然std::vector<Datapoint> datapoints只包含一块连续内存,但其中的元素std::vector<Cluster> clusters包含我想要预取和固定的 std::vectors 本身。我不认为有一些开箱即用的递归解决方案,所以 - 如果有第一个问题的解决方案(我绝对肯定有,因为例如 OpenGL 驱动程序也可以这样做) - 是否有某种订阅回调的方式,以便我可以std::vector<Cluster> clusters在完全固定时收到通知,以便我可以遍历它以请求固定每个集群元素std::vector<size_t> indicesstd::vector<float> weights每个集群元素?

  3. 执行情况如何void Unpin(const Tile& tile)

  4. 额外问题:我在 Xeon Gold CPU 上运行,每个内核具有 1MB 的二级缓存。大多数图块只有几百 KB。所以我想知道除此之外Pin(tiles[i+100]);我是否还可以实现MoveToL2(tiles[i+1]);将下一次迭代的数据预取到 L2 内存中。如果是这样,我该如何实施?

标签: c++performancememoryprefetch

解决方案


推荐阅读