我一直在分析我的代码(如下所示的函数)中的一个瓶颈,该瓶颈被调用了数百万次。我可以使用提高性能的技巧。 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 }
有什么想法吗?
感谢大佬指教。以下是我从建议中得到的结果:
我发现切换到 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/