C 循环展开限制?
C loop unrolling limitations?
我正在对 C for 循环进行优化,我刚刚阅读了有关展开和累加器的内容。如果数据在循环中不相互依赖,则展开和累加器的使用真正利用了并行性,并且代码完成得更快。
所以我天真的想法是,为什么不添加更多累加器并展开更多次?
我这样做了,并注意到每个元素的平均周期减少了returns。
我的问题是为什么?
答:是不是因为我们运行没有寄存器可以同时使用,信息需要存储在内存中?
B: 还是因为'cleanup loop'展开循环后要处理更多的元素?
是A和B的组合吗?
更有可能,A。我不久前见过。我自己做了同样的问题,得出的结论是我 运行 超出了寄存器,所以不再有快速累加器。用于处理未展开的其余元素的清理代码 运行 比主展开循环的时间少得多。
我不确定我在这里是否只是在陈述显而易见的事实,但是 main 您看到展开减少 returns 的原因仅仅是因为您已经在很大程度上消除了循环的开销,CPU 上的剩余时间几乎全部花在了您正在做的 "useful" 工作上。
展开的好处是您消除了循环本身的开销——即索引增量、比较、分支等。 -- 并不是说它使循环的有用工作更快。当您达到循环开销大部分被消除的程度时,很明显您不会看到更多展开带来的进一步改进。
另一方面,进一步展开肯定会在某些方面使性能变差,例如寄存器溢出到内存,I-cache 工作效率较低,循环对于 trace-cache 来说太大(on运动的处理器) &c.
我正在对 C for 循环进行优化,我刚刚阅读了有关展开和累加器的内容。如果数据在循环中不相互依赖,则展开和累加器的使用真正利用了并行性,并且代码完成得更快。
所以我天真的想法是,为什么不添加更多累加器并展开更多次?
我这样做了,并注意到每个元素的平均周期减少了returns。
我的问题是为什么?
答:是不是因为我们运行没有寄存器可以同时使用,信息需要存储在内存中?
B: 还是因为'cleanup loop'展开循环后要处理更多的元素?
是A和B的组合吗?
更有可能,A。我不久前见过。我自己做了同样的问题,得出的结论是我 运行 超出了寄存器,所以不再有快速累加器。用于处理未展开的其余元素的清理代码 运行 比主展开循环的时间少得多。
我不确定我在这里是否只是在陈述显而易见的事实,但是 main 您看到展开减少 returns 的原因仅仅是因为您已经在很大程度上消除了循环的开销,CPU 上的剩余时间几乎全部花在了您正在做的 "useful" 工作上。
展开的好处是您消除了循环本身的开销——即索引增量、比较、分支等。 -- 并不是说它使循环的有用工作更快。当您达到循环开销大部分被消除的程度时,很明显您不会看到更多展开带来的进一步改进。
另一方面,进一步展开肯定会在某些方面使性能变差,例如寄存器溢出到内存,I-cache 工作效率较低,循环对于 trace-cache 来说太大(on运动的处理器) &c.