【问题标题】:Reversing the order of a nested loop without using extra memory在不使用额外内存的情况下反转嵌套循环的顺序
【发布时间】:2012-08-31 17:48:17
【问题描述】:

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

我有一个嵌套循环(在着色器程序中),它执行这样的操作(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],然后这样做:

对于每个 L Q[i] = Li // 存入数组

然后遍历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[] 数组的情况下以代数方式做到这一点。

* 双关语意

【问题讨论】:

    标签: optimization loops for-loop nested algebra


    【解决方案1】:

    一种没有嵌套循环的方式:

    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)

    【讨论】:

    • 这真是太好了,只是我忽略了要先找到B与每个L的关系。让我把它考虑进去。
    【解决方案2】:

    我可能把问题弄错了,但L1*B1*B2*B3 + L2*B1*B2*B3 不等于(L1+L2)*B1*B2*B3

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-29
      • 1970-01-01
      • 2020-04-09
      • 2021-11-04
      相关资源
      最近更新 更多