我必须在下面针对循环代码进行优化。我能怎么做?有什么建议吗?我试图展开循环,但它没有改变任何东西。 感谢。
G是图的矩阵(有向或无向图) 代码如下:
void col_convert(int dim, int *G)
{
int i, j;
for (i = 0; i < dim; i++)
for (j = 0; j < dim; j++)
G[j*dim+i] = G[j*dim+i] || G[i*dim+j];
}
修改 最常见的维度是8。
答案 0 :(得分:2)
通过注意操作是对称的,可以将迭代次数减半:
void naive_col_convert(int dim, int *G) {
for (int i = 0; i < dim; i++) {
G[i * dim + i] = G[i * dim + i] != 0;
for (int j = i + 1; j < dim; j++) {
G[i * dim + j] = G[j * dim + i] = G[j * dim + i] || G[i * dim + j];
}
}
}
编辑:如果最常见的值为8,请使用-O3
尝试以下代码。编译器应该能够从相同的源代码为特殊情况生成有效的代码。
void naive_col_convert(int dim, int *G) {
if (dim == 8) {
#define dim 8
for (int i = 0; i < dim; i++) {
G[i * dim + i] = G[i * dim + i] != 0;
for (int j = i + 1; j < dim; j++) {
G[i * dim + j] = G[j * dim + i] = G[j * dim + i] || G[i * dim + j];
}
}
#undef dim
} else {
for (int i = 0; i < dim; i++) {
G[i * dim + i] = G[i * dim + i] != 0;
for (int j = i + 1; j < dim; j++) {
G[i * dim + j] = G[j * dim + i] = G[j * dim + i] || G[i * dim + j];
}
}
}
}
如果性能改进不显着,您可以手动将循环展开到36个语句的序列上。对这些语句进行重新排序可能会对选定的体系结构产生额外的改进,而对其他语句的操作则会更慢。
答案 1 :(得分:0)
我比原始代码加速了5.4倍。谢谢大家。
这就是答案:
void col_convert(int dim, int *G)
{
int i, j,dimj,dimi,nj,ni;
for (i = 0; i <= dim-8; i +=8){
ni = dim * i;
for (j = 0; j < dim; j++)
{
nj = j * dim ;
dimj = nj + i;
dimi = ni + j;
G[dimj] |= G[dimi];
dimj += 1;
dimi += dim;
G[dimj] |= G[dimi];
dimj += 1;
dimi += dim;
G[dimj] |= G[dimi];
dimj += 1;
dimi += dim;
G[dimj] |= G[dimi];
dimj += 1;
dimi += dim;
G[dimj] |= G[dimi];
dimj += 1;
dimi += dim;
G[dimj] |= G[dimi];
dimj += 1;
dimi += dim;
G[dimj] |= G[dimi];
dimj += 1;
dimi += dim;
G[dimj] |= G[dimi];
}
}
// Use the normal loop for any remaining elements
for (; i < dim; i++){
ni = i * dim;
for (j = 0; j < dim; j++){
nj = j * dim;
dimj = nj + i;
dimi = ni + j;
G[dimj] |= G[dimi];
}
}
}