繁体   English   中英

用于高性能计算的 C++ 类

[英]C++ Classes for High Performance Computing

根据这个 Quora 论坛

最简单的经验法则之一是记住硬件喜欢数组,并且针对数组迭代进行了高度优化。 许多问题的一个简单优化就是停止使用花哨的数据结构,只使用普通数组(或 C++ 中的 std::vectors)。 这可能需要一些时间来适应。

C++ 类是否属于那些“花哨的数据结构”,即一种可以用数组替换以在 C++ 程序中实现更高性能的数据类型?

如果你的类看起来像这样:

struct Person {
  double age;
  double income;
  size_t location;
};

那么你可能会受益于重新排列

std::vector<double> ages;
std::vector<double> incomes;
std::vector<size_t> locations;

但这取决于您的访问模式。 如果您一次经常访问一个人的多个元素,那么将这些元素屏蔽在一起是有意义的。

如果你的类看起来像这样:

struct Population {
  std::vector<double> many_ages;
  std::vector<double> many_incomes;
  std::vector<size_t> many_locations;
};

然后您正在使用您的资源推荐的表单。 单独使用这些数组中的任何一个都比使用第一类更快,但同时使用来自所有三个数组的元素可能会比第二类更慢。

最终,您应该将代码构建得尽可能干净和直观。 速度的最大来源将是对算法的深刻理解和适当使用,而不是内存布局。 我建议您忽略这一点,除非您已经拥有强大的 HPC 技能并且需要从您的机器中获得最大性能。 在几乎所有其他情况下,您的开发时间和理智远比节省几个时钟周期更有价值。

更广泛地

  1. 与此相关的一篇有趣的论文是SLIDE: In Defense of Smart Algorithms over Hardware Acceleration for Large-Scale Deep Learning Systems 在将 ML 算法映射到 GPU 方面进行了大量工作,对于 ML 应用程序,正确的内存布局确实会产生真正的不同,因为在训练上花费了大量时间,并且 GPU 专门针对连续数组处理进行了优化。 但是,该论文的作者认为,即使在这里,如果您很好地理解算法,您也可以击败具有优化内存布局的专用硬件,他们通过让 CPU 的训练速度比 GPU 快 3.5 倍来证明这一点。

  2. 更广泛地说,您的问题涉及缓存未命中的想法。 由于缓存未命中比 L1 引用(链接)贵 200 倍,如果您的数据布局针对您的计算进行了优化,那么您真的可以节省时间。 然而,正如上面所暗示的那样,简单地重新排列数据神奇地使一切变得更快的情况很少见。 考虑矩阵乘法。 这是一个完美的例子,因为数据按照您的资源的要求排列在单个数组中。 然而,对于一个简单的三循环 matmult GEMM 实现,仍然有 6 种方法来安排循环。 其中一些方法比其他方法更有效,但没有一种方法能让您获得接近峰值的性能。 通读matmult 的分步说明,以更好地了解获得良好性能所需的所有算法优化。

上面应该证明的是,即使在我们只有几个数组完全按照您的资源建议布局的情况下,仅靠布局并不能给我们带来速度。 好的算法可以。 数据布局考虑(如果有)来自我们选择的算法和更高级别的硬件约束。

如果对于简单的数组和矩阵乘法等操作来说是这样,那么通过扩展,您也应该期望“花式数据结构”也是如此。

C++ 类是那些“花哨的数据结构”之一吗?

我认为他们特别指的是像std::mapstd::dequestd::list等容器,这些容器在许多不同的堆分配中保存数据,因此迭代容器的内容需要 CPU“跳来跳去” " 在某种程度上在 RAM 地址空间中,而不仅仅是顺序读取 RAM。 正是这种跳跃常常限制了性能,因为当未来的 RAM 访问位置不容易预测时,CPU 的板载内存缓存在避免由于 RAM 延迟而导致的执行停顿方面效率较低。

C++ 类本身可能会也可能不会鼓励非顺序 RAM 访问; 它是否完全取决于类是如何实现的(特别是它是否通过多个堆分配保存其数据)。 std::vector类(在论坛文本中提到)是 C++ 类的一个示例,它在您遍历其内容时不需要任何非顺序内存访问。

C++ 类是那些“花哨的数据结构,

C++ 类是一种可用于创建数据类型的构造。 它可用于创建数据结构,例如列表、队列等。

即一种数据类型

类是一种数据类型

可以用数组代替

类和数组不可互换。 数组是数据结构。 你在比较苹果和橙子。

在 C++ 程序中获得更高的性能?

这取决于你如何实现你的类

C++ 类是否属于那些“花哨的数据结构”,即一种可以用数组替换以在 C++ 程序中实现更高性能的数据类型?

计算机时间和您的开发时间都很宝贵。

除非您确定代码占用了大部分 CPU 时间,否则不要优化代码。

所以首先使用 分析器(例如Gprof )并阅读您的 C 或 C++ 编译器(例如GCC )的文档。 编译器能够进行花哨的优化。

如果您真的关心 HPC,请了解使用OpenCLOpenACC 等GPGPU 编程。

如果您碰巧使用 Linux(HPC 世界中的常见操作系统),请阅读Advanced Linux Programming ,然后是syscalls(2) ,然后是time(7)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM