在不使用额外内存的情况下反转嵌套循环的顺序

时间:2012-08-31 17:48:17

标签: optimization loops for-loop nested algebra

我不确定这是一个数学(代数)问题还是一个编程问题。

我有一个嵌套循环(在着色器程序中)做类似这样的事情(L和B是只读的):

for each L in (L1, L2)
  Q=L
  for each B in (B1, B2, B3)
    Q *= B
  result += Q

所以这个循环的结果是:

result += L1*B1*B2*B3 + L2*B1*B2*B3

这是正确的结果,但是B的访问速度很慢,L的访问速度很快。因此,在内循环中迭代B的速度比在内循环中迭代L慢得多(我在上面读取每个B 两次,每次L读一次)。

如果我们天真地逆转内/外循环,

for each B in (B1, B2, B3)
  Q=B
  for each L in (L1, L2)
    Q *= L
  result += Q

当然这个结果变成了

result += B1*L1*L2 + B2*L1*L2 + B3*L1*L2

我在这里读过一次B,但结果不对。我需要L1*B1*B2*B3形式的产品。我知道我可以创建一个数组Q[2]并且只做:

for each L
  Q[i] = Li // save in array

然后迭代B:

for each B in (B1, B2, B3)
  for i = 1..2
    Q[i] *= B

result += Q[i]

哪个给出了

result += Q[1]*B1*B2*B3 + Q[2]*B1*B2*B3

这是正确的,但如果L很大(确实如此),那就会浪费内存。我想知道我是否可以在没有中间L[]数组的情况下以代数方式执行此操作。

*双关语

2 个答案:

答案 0 :(得分:2)

没有嵌套循环的方法:

result = 0
for each L in (L1, L2)
  result += L
for each B in (B1, B2, B3)
  result *= B

因为

L1*B1*B2*B3 + L2*B1*B2*B3

缩减为

B1*B2*B3*(L1+L2)

答案 1 :(得分:0)

我可能会错误地提出错误但问题L1*B1*B2*B3 + L2*B1*B2*B3是否等于(L1+L2)*B1*B2*B3