【问题标题】:Memory usage an parallel programming内存使用并行编程
【发布时间】:2013-04-02 15:47:24
【问题描述】:

我对并行计算了解不多,但我想就某项作业的“进一步工作”提出建议,并希望确保我是对的。 我用 C++ 编写了一个光线追踪器。我在vector 中存储了射线的信息,例如命中点,并在模拟结束时将这些向量写入 CSV(这是好的编程吗?)如果我跟踪许多射线,比如 1000 条,则比较模拟需要更多时间跟踪 100 条光线 10 次。我认为这是因为我的vector's 的大小更大,因此它们在堆内存中占用了大量空间(?)。每条光线都可以在没有来自其他光线的信息的情况下被追踪(程序正在乞求并行)。我是否正确地说,如果程序是并行的,每个处理器都将拥有自己的内存,因此不会有一个大向量占用一大块内存,而是散布在周围的小向量可以更有效地处理?

【问题讨论】:

  • 或者让程序线程化 (std::thread) 以允许并行执行。
  • 很可能您在 1x1000 与 10x100 测试中使用了不同的光线。如果是这样,我会调查相同的光线正在测量它们的时间。我愿意打赌一个不那么小的身体部位,向量的大小完全无关紧要。主存速度以 GB/s 为单位测量 - “一对”(数千或百万)额外元素对执行速度没有明显影响。为什么不编写一些分析代码来查看向量的速度(或查找其他人的结果)QueryHighPerformanceFrequency 和 QueryHighPerformanceTimer - 如果在 Windows 上工作,它们都很方便。
  • 好的 - 这基本上回答了我的问题。与较小的向量相比,具有几百万个元素的向量不会对模拟产生实质性影响。谢谢

标签: c++ memory parallel-processing


【解决方案1】:

您对每个处理器都有自己的“内存”的假设听起来像是在尝试提高 CPU 缓存的使用率(无论您的任务有多并行,RAM 都保持不变 - 除非您将其分布在集群上)。虽然通常并行化提供了更多的 CPU 缓存,但由于线程将在内核之间迁移(Windows 确实这样做),因此可能会有更多的缓存未命中。

也许您只是在以一种低效的方式使用 std::vector。例如。您在开头插入项目或一个接一个地附加项目(这些操作可能需要 O(vector.size()))。或者当光线数量增加时,可能存在其他数据结构变慢。这可能无需在多个处理器之间拆分任务即可解决。

虽然程序肯定会从并行化中获益。

【讨论】:

  • 这正是我正在做的。我从来没有被要求“处理”我的结果,所以我付出了很多努力来有效地追踪穿过场景的光线。但是为了表明我所做的实际上是正确的,每次射线击中一个对象时,我都会在vector 上附加该命中点的坐标并继续计算。最后,我将该向量写入 csv 并使用 Matlab 绘制漂亮的图片 - 有没有一种快速修复的方法?
  • 向量中元素的最终数量是多少?您可以将向量的容量设置为此数字(或更大一点)以避免在添加新元素时重新分配内存:your_vector.reserve(1000000);(假设您将存储最多 1000000 个项目)更智能的方法可能是为这个输出数据并最终将其刷新到 CSV 文件,而不是将所有内容存储在 RAM 中并在最后进行一次大写。
  • 我考虑过调整矢量的大小,但不幸的是,光线可以在整个场景中反弹,因此命中点的数量将远远大于对象的数量。对于缓冲区,我理解你的意思吗:我有一个vector.reserve(100000k),当它达到容量时,我会定期将它写入 CSV?
  • 当然。但我认为您已经知道 1000 射线测试的命中点数量,因此很容易尝试查看问题出在矢量还是其他地方。然后你可以实现更智能的方案(如果你不喜欢最终将结果写入文件,你可以让向量大块地增长:而不是v.append() 写像if (v.capacity() == v.size()) { v.reserve(v.capacity() + (1<<20)); } v.append(...); 这样的东西,从而使向量一次增长 2^20 个项目。
猜你喜欢
  • 2021-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多