[英]Ranges of nested for-loops when locality is improved (C++)
I have the following nested for loop: 我有以下嵌套的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++;
}
}
Which prints (0,1) to (6,7) as expected and the printf()
statement is ran 28 times as indicated by counter
. 如预期那样打印(0,1)至(6,7),并且
printf()
语句运行了28次,如counter
。
I have been the set the task of improving the efficiency of this code by improving its locality (this is test code, the value of n
in the actual program is much larger and i
and j
are used to index into two 1d arrays) and have employed what I believe to be a fairly standard technique: 我已经承担了通过改善代码局部性来提高代码效率的任务(这是测试代码,实际程序中的
n
值要大得多,并且i
和j
用于索引到两个1d数组中)使用了我认为是相当标准的技术:
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++;
}
However, here printf()
is only being ran 24 times because the j_chunk = i_chunk + 1
means that where before the j
loop printed (0,1) to (0,7), the two iterations of the j_chunk
loop where i+i_chunk == 0
print (0,1) to (0,3) and (0,5) to (0,7) missing (0,4). 但是,这里的
printf()
仅运行了24次,因为j_chunk = i_chunk + 1
表示在j
循环打印(0,1)到(0,7)之前, j_chunk
循环的两次迭代是i+i_chunk == 0
打印(0,1)至(0,3)和(0,5)至(0,7)缺少(0,4)。
I understand why it is doing this but I can't for the life of me come up with a solution; 我知道为什么这样做,但是我无法为自己的生活提出解决方案; any help would be appreciated.
任何帮助,将不胜感激。
First you need to make sure that j
is never in a lower chunk than i
, so your outer loops should be: 首先,您需要确保
j
永远不会比i
低,因此您的外部循环应为:
for(int i = 0; i < n; i+=chunk)
for(int j = i; j < n; j+=chunk)
Then you need different behaviour based on whether i
and j
are in the same chunk or not. 然后,根据
i
和j
是否在同一块中,您需要不同的行为。 If they are, j_chunk
needs to allways be larger than i_chunk
, otherwise you need to go through all possible combinations: 如果是,则
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++;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.