有人可以首先解释在什么时候展开循环(在C / C ++中)成为一个有用的优化?
其次,与第一个问题相关,在什么时候应该不再进行展开?是否应始终将展开操作拆分为2次?或者它与您的CPU可以执行多少计算有关?比率是您的缓存行大小的乘数?等
例如,如果我有一个从0到99的for循环哪个更好/我如何确定哪个(除了试验和错误) - 是否有科学方法:
答案 0 :(得分:6)
我不能在没有提到Duff's Device的情况下让关于循环展开的问题没有得到答复。此实现与经典版本略有不同,但它仍然有效。
假设您正在将掩码应用于内存块:
while (n-- > 0) {
*ptr++ &= mask;
}
然后,这可以像这样展开:
switch (n % 4) do {
case 0: *ptr++ &= mask;
case 3: *ptr++ &= mask;
case 2: *ptr++ &= mask;
case 1: *ptr++ &= mask;
} while ((n -= 4) > 0);
如果迭代跳转的成本占循环迭代内完成工作成本的很大一部分,则循环展开非常有用。一个好的优化编译器可以在足够的优化级别为您找出答案。如果你的编译器没有这样做,你只需要自己展开它。
如评论中所述,一旦与展开的循环体的计算相比,跳跃的计算成本不再显着,则无需展开。从极端开始,循环展开可能会导致指令缓存捶打,从而损害性能(类似于过度使用函数内联)。