【发布时间】:2016-05-20 19:20:50
【问题描述】:
我有以下代码,它为嵌套 for 循环的变量生成数字/索引的组合
#include <iostream>
#include <array>
template<size_t ... Rest>
inline void index_generator() {
constexpr int size = sizeof...(Rest);
std::array<int,size> maxes = {Rest...};
std::array<int,size> a;
int i,j;
std::fill(a.begin(),a.end(),0);
while(1)
{
for(i = 0; i<size; i++) {
std::cout << a[i] << " ";
}
std::cout << "\n";
for(j = size-1 ; j>=0 ; j--)
{
if(++a[j]<maxes[j])
break;
else
a[j]=0;
}
if(j<0)
break;
}
}
int main()
{
index_generator<2,3,3>();
return 0;
}
输出如下
0 0 0
0 0 1
0 0 2
0 1 0
0 1 1
0 1 2
0 2 0
0 2 1
0 2 2
1 0 0
1 0 1
1 0 2
1 1 0
1 1 1
1 1 2
1 2 0
1 2 1
1 2 2
这确实相当于拥有
for (int i=0; i<2; ++i)
for (int j=0; j<3; ++j)
for (int k=0; i<3; ++k)
我可以使用上述方法生成任意数量的 nested for loops 的等价物,但是我注意到随着循环数量的增加,与对应的对应物(即嵌套 for 循环)相比,此代码的执行速度越来越慢。我已经检查了gcc 5.3 和clang 3.8。这可能是因为处理器很难预测while(true) 中的分支,或者可能是其他原因。
我在最内层循环中所做的通常是访问两个数组中的数据并对它们进行乘法运算,例如 c_ptr[idx] +=a_ptr[idx]*b_ptr[idx]。由于使用嵌套 for 循环和使用上述技术生成的索引是相同的,所以 内存访问模式 保持不变。因此,就数据访问而言,我很确定这不是缓存未命中/命中问题。
所以我的问题是:
- 有没有办法像嵌套 for 循环样式代码一样快速生成这些组合/索引,甚至可能更快?
- 既然我们知道要设置的 for 循环的数量和 for 循环的索引在编译时是已知的,那么是否可以不利用更好的优化机会?例如 SIMD?
【问题讨论】:
-
你有多少个嵌套循环?
-
嵌套循环的数量没有限制。
标签: c++ performance loops c++11