c++ - 优化循环性能

标签 c++ performance c++11

我一直在分析我的代码(如下所示的函数)中的一个瓶颈,该瓶颈被调用了数百万次。我可以使用提高性能的技巧。 XXXs 号码取自 Sleepy .

使用 visual studio 2013、/O2 和其他典型发布设置编译。

indicies 通常是 0 到 20 个值,其他参数大小相同 (b.size() == indicies.size() == temps.size() ==温度[k].size()).

1:          double Object::gradient(const size_t j, 
2:                                  const std::vector<double>& b, 
3:                                  const std::vector<size_t>& indices, 
4:                                  const std::vector<std::vector<double>>& temps) const
5:  23.27s  {
6:              double sum = 0;
7:  192.16s     for (size_t k : indices)
8:  32.05s          if (k != j)
9:  219.53s             sum += temps[k][j]*b[k];
10:      
11: 320.21s     return boost::math::isfinite(sum) ? sum : 0;
13: 22.86s  }

有什么想法吗?

感谢大佬指教。以下是我从建议中得到的结果:

enter image description here

我发现切换到 cbegin()cend() 会产生如此大的影响,这很有趣。我猜编译器并没有那么聪明。我对这个凸起很满意,但仍然好奇这里是否通过展开或矢量化有更多空间。

对于那些感兴趣的人,这里是我的 isfinite(x) 基准:

boost::isfinite(x):
------------------------
SPEED: 761.164 per ms
TIME:  0.001314 ms
   +/- 0.000023 ms

std::isfinite(x):
------------------------
SPEED: 266.835 per ms
TIME:  0.003748 ms
   +/- 0.000065 ms

最佳答案

如果您知道条件将得到满足(在每次迭代中您将满足 k == j),请消除条件并用简单的条件存储替换返回条件。

double sum = -(temps[j][j]*b[j]);
for (size_t k : indices)
     sum += temps[k][j]*b[k];
if (!std::isfinite(sum))
     sum = 0.0;
return sum;

基于范围的 for 仍然很新,并不总能得到很好的优化。您可能还想尝试:

const auto it = cend(indices);
for (auto it = cbegin(indices); it != end; ++it) {
    sum += temps[*it][j]*b[*it];
}

并查看性能是否变化。

关于c++ - 优化循环性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31082160/

相关文章:

c++ - 多重映射如何在内部处理重复键?

mysql - 如何提高 JavaFx-MySQL 应用程序的性能

c++ - 在 c++11 中实现 Haskell 的 Maybe Monad

c++ - 错误 C2039 : 'find' : is not a member of 'std'

c++ - 如何正确关闭在 Glade 中创建的对话框?

c++ - vector.push_back 分配内存失败

c - 存储更多 bool 值的最有效方法

java - 创建新变量与重用旧变量哪个更快?

c++ - 通过引用传递对象到std::thread in C++11

c++ - 一个互斥锁与多个互斥锁。线程池用哪个好?