C++ std::转换比for循环慢

C++ std::转换比for循环慢,c++,matrix,c++17,C++,Matrix,C++17,我曾想过实现一个矩阵类,它使用算法中的std::transform进行计算,但在某些情况下,编写循环会更快 查看元素添加的add操作符+=。如果rhs矩阵有1列,但行数与lhs矩阵相同,我可以执行以下操作: for (auto c = 0; c < cols(); ++c) { std::transform(std::execution::par, col_begin(c), col_end(c), rhs.begin(), col_begin(c), std::plus<&

我曾想过实现一个矩阵类,它使用算法中的
std::transform
进行计算,但在某些情况下,编写循环会更快

查看元素添加的add
操作符+=
。如果rhs矩阵有1列,但行数与lhs矩阵相同,我可以执行以下操作:

for (auto c = 0; c < cols(); ++c) {
    std::transform(std::execution::par, col_begin(c), col_end(c), rhs.begin(), col_begin(c), std::plus<>());
}
(自动c=0;c 或者使用简单的循环:

auto lhsval = begin();
auto rhsval= rhs.begin();

for (auto r = 0; r < rows(); ++r) {
   for (auto c = 0; c < cols(); ++c) {
       *lhsval += *rhsval;
       ++lhsval;
   }
   ++rhsval;
}
auto-lhsval=begin();
auto rhsval=rhs.begin();
对于(自动r=0;r
为供参考,我编写了一个接受步骤的迭代器。因此,
col\u begin()
返回一个迭代器,该迭代器将跳过
操作符+++

我使用googlebenchmark对两种实现之间的差异进行了计时,并得出结论,循环速度大约是使用std::transform的5倍。也许应该有区别,但区别不是那么大

您可以在以下位置查看完整的代码:


传递
std::execution::par
要求库并行化此操作。这增加了开销,即使只是为了确定“您的问题太小,无法并行化”。在进行并行化之前,被转换的元素的数量必须相当大(有时是几十万或数百万),并且需要有适当的硬件(在两核机器上进行并行化比在64核机器上进行并行化要少得多)


循环版本的
与没有
std::execution::par
参数的普通
std::transform
非常相似。如果删除该参数且性能差异仍然很大,请使用该信息更新您的问题,以及编译器版本、平台、编译器开关和有关数据集的信息:行/列数等。

如果没有
std::execution::par
,是否会发生同样的情况?您是在发布模式下编译的吗?提示:当询问性能(而不是效率)时,如果不指定如何编译代码,这些问题通常是无法回答的。我们需要-您的编译器、您的构建(调试/发布)和您的编译器选项(主要是优化标志)。在第一个示例中,您在两个未连接的内存区域上迭代多次。在第二种情况下,您只使用单个rhs值迭代一个区域,该值可以通过compiler@bazz-迪,它一点也不大。缓存未命中(及其子类型,分支预测失误)会在低级别上造成巨大的性能问题。另外,我在代码中注意到矩阵是如何组织的。难怪对行和列进行迭代的速度更快——行中的单元格在内存中靠得很近,在一条缓存线中。尝试反转for循环,然后检查性能。我非常确信(若编译器并没有优化它),它将几乎和我们的代码示例看起来不一样的慢。确保他们做同样的事情。发一封邮件,你好。测试数据为1000x1000矩阵。在评论中,您可以看到其他信息。但我认为我的评论是正确的,我只是有缓存未命中。目前我找到了一种足够快的解决方案