【问题标题】:Basic algebra operations on known size arrays已知大小数组的基本代数运算
【发布时间】:2019-08-01 09:17:10
【问题描述】:

我是一个从 Fortran 过渡的新手 c++ 开发人员。 我正在尝试编写 最有效 可能的函数来计算两个编译时已知大小 std::arrays 的差异范数(通常在 1 到 10 之间,最常见的是

也许一个简单的解决方案已经存在于专用库(如 Boost 或 Eigen)中?我对这些了解太少,无法确定。

最好的,

【问题讨论】:

  • 你必须测量才能确定,但​​我会说它们应该是等价的。
  • 如果您想知道,那么下一步就是尝试这些替代方案并为它们计时。对于效率问题,确实没有普遍适用的答案。
  • 标准算法的性能通常不比手写代码差。交易是:零开销的很棒的抽象。 不是:你的代码会自动变得更快
  • 根据问题(以及您要解决的平台),您可以通过并行化获得一些速度。许多标准算法允许通过execution policies(例如std::sort)进行并行化,您可以使用这些算法。如果你没有找到合适的,有像Open MP这样的并行化库。
  • 还没有提到的东西,如果你的数组在编译时被填充(或可以被填充),那么你可以使用constexpr 来计算这种东西(没有运行时成本!)。您必须为此编写自己的函数,因为标准函数还不是 constexpr。详情见stackoverflow.com/questions/33157731/…

标签: c++ numeric


【解决方案1】:

手写循环和标准算法很可能产生相同的代码。无论如何,我不希望合理的编译器有有意义的性能差异。

这里真正的性能提升必须来自矢量化。

  • 自动向量化在编译器之间变化很大(浮点运算可能默认关闭,因为它们不是关联的)。理论上,使用带有std::execution::parallel_unsequenced_policy(或C++20 中的std::execution::unsequenced_policy)的标准算法应该向编译器暗示他们可以/应该对循环代码进行向量化,但目前编译器对此的采用率很低。

  • 您可以手写矢量化代码,但这可能很难获得好的/正确的。除非您知道该部分对性能至关重要,否则这肯定不是您的时间的有效投资。

  • 某些库可能已经为此类操作提供了适当的矢量化代码。我希望 Eigen 和可能 ublasarmadillolapack 能够解决这个问题。但是您必须自己检查它们,以及它们是否满足您给定平台的需求。

一如既往:如果您关心性能,请衡量和比较。没有通用的答案。

【讨论】:

  • 嗯。实际上我什至没有考虑矢量化。感谢您的提示。
猜你喜欢
  • 2011-08-27
  • 1970-01-01
  • 2017-06-02
  • 2013-11-27
  • 2021-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-17
相关资源
最近更新 更多