改进局部性时嵌套for循环的范围(C ++)

时间:2017-10-22 18:14:29

标签: c++ nested-loops cache-locality

我有以下嵌套for循环:

int n = 8;
int counter = 0;

for (int i = 0; i < n; i++)
{
    for (int j = i + 1; j < n; j++)
    {
        printf("(%d, %d)\n", i, j);
        counter++;
    }
}

按预期打印(0,1)到(6,7),printf()语句按counter的指示运行28次。

我一直致力于通过改进地方性来提高此代码的效率(这是测试代码,实际程序中n的值更大,i和{ {1}}用于索引两个1d数组)并采用了我认为相当标准的技术:

j

但是,这里int chunk = 4; for(int i = 0; i < n; i+=chunk) for(int j = 0; j < n; j+=chunk) for (int i_chunk = 0; i_chunk < chunk; i_chunk++) for (int j_chunk = i_chunk + 1; j_chunk < chunk; j_chunk++) { printf("(%d, %d)\n", i+i_chunk, j+j_chunk); counter++; } 只运行了24次,因为printf()表示在j_chunk = i_chunk + 1循环打印(0,1)到(0,7)之前的位置, j循环的迭代,其中j_chunk打印(0,1)到(0,3)和(0,5)到(0,7)缺失(0,4)。

我理解为什么会这样做,但我不能为我的生活提出解决方案;任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

首先,您需要确保j永远不会低于i,因此您的外部循环应该是:

for(int i = 0; i < n; i+=chunk)
   for(int j = i; j < n; j+=chunk)

然后,根据ij是否在同一块中,您需要不同的行为。如果是,j_chunk需要总是大于i_chunk,否则您需要经历所有可能的组合:

if(i==j)
{
    for (int i_chunk = 0; i_chunk < chunk; i_chunk++)
    {
        for (int j_chunk = i_chunk + 1; j_chunk < chunk; j_chunk++)
        {
            printf("(%d, %d)\n", i+i_chunk, j+j_chunk);
            counter++;
        }
    }
}
else
{
    for (int i_chunk = 0; i_chunk < chunk; i_chunk++)
    {
        for (int j_chunk = 0; j_chunk < chunk; j_chunk++)
        {
            printf("(%d, %d)\n", i+i_chunk, j+j_chunk);
            counter++;
        }
    }
}