当编译器执行循环展开优化时,它如何确定展开循环或是否展开整个循环?由于这是空间性能的权衡,平均而言,这种优化技术在使程序性能更好方面的效果如何?此外,建议在什么条件下使用这种技术(即某些操作或计算)?
这不必特定于某个编译器。它可以是任何解释,概述该技术背后的想法以及在实践中观察到的内容。
当编译器执行循环展开优化时,它如何确定展开循环或是否展开整个循环?由于这是空间性能的权衡,平均而言,这种优化技术在使程序性能更好方面的效果如何?此外,建议在什么条件下使用这种技术(即某些操作或计算)?
这不必特定于某个编译器。它可以是任何解释,概述该技术背后的想法以及在实践中观察到的内容。
当编译器执行循环展开优化时,它如何确定展开循环的因素或天气是否展开整个循环。
堆栈消耗和局部性。指令计数。基于展开和内联程序进行/传播优化的能力。循环大小是固定的,还是预期在某个范围内。配置文件输入(如果适用)。可以从循环体中删除的操作。等等
由于这是平均空间性能权衡,这种优化技术在使程序性能更好方面的效果如何?
这在很大程度上取决于输入(您的程序)。它可能会更慢(不典型),也可能会快几倍。学习编写一个程序以优化运行,并使优化器能够完成其工作。
此外,建议在什么条件下使用此技术(即某些操作或计算)
通常,在非常小的主体上进行大量迭代,尤其是那些无分支且具有良好数据局部性的主体。
如果您想知道该选项是否对您的应用、个人资料有帮助。
如果你需要更多,你应该预留一些时间来学习如何编写最佳程序,因为这个主题相当复杂。
简单的分析是对指令进行计数 - 展开 10 次的 2 指令循环有 11 条指令而不是 20 条指令,从而产生 11/20 的加速。但是对于现代处理器架构,它要复杂得多。取决于缓存大小和处理器指令流水线的特性。上述示例的运行速度可能会快 10 倍而不是 2 倍。展开 1000x 而不是 10x 也可能会运行得更慢。如果不针对特定处理器,编译器(或您为它们编写的编译指示)只是猜测。
当(在我看来)展开循环很好时:
循环很短,可能所有使用的变量都在处理器寄存器中。展开后变量是“重复的”,但仍然在寄存器中,因此没有内存(或缓存)损失。
循环(具有未知的循环展开编号)将至少执行几次或几十次,因此有理由将展开的整个循环加载到指令缓存中。
如果循环很短(一个或几个指令),它可能对展开非常有益,因为用于确定是否应该再次执行的代码执行频率较低。
好的,首先,我不知道编译器如何自动执行此操作。而且我很确定编译器必须从中选择至少 10 种算法,如果不是 100 种算法的话。
无论如何,它可能是特定于编译器的。
但是,我可以帮你计算它的有效性。
请注意,这种技术通常不会给您带来很大的性能提升。
但在重复循环计算中并能给出很高的百分比性能。
这是因为通常循环内的函数比循环的条件检查花费更多的计算时间。
因此,假设我们有一个带有常量的简单循环,因为您懒得进行复制粘贴,或者只是认为它看起来会更好:
for (int i = 0; i < 5; i++)
{
DoSomething();
}
这里有5 个int 比较、5 个增量和5 个DoSomethig() 调用。
因此,如果 DoSomething() 相对较快,那么我们就有15次操作。
现在,如果你展开这个,你将把它减少到只有 5 个操作:
DoSomething();
DoSomething();
DoSomething();
DoSomething();
DoSomething();
现在使用常量更容易,让我们看看它如何使用变量:
for (int i = 0; i < n; i++)
{
DoSomething();
}
在这里,您有n 个int 比较、n 个增量和n 个DoSomethig() 调用 = 3n。现在,我们不能完全展开它,但我们可以通过一个常数因子展开它(预期的n越高,我们应该展开的越多):
int i;
for (i = 0; i < n; i = i+3)
{
DoSomething();
DoSomething();
DoSomething();
}
if (i - n == 2)
{
DoSomething(); // We passed n by to, so there's one more left
}
else if (i - n == 1)
{
DoSomething(); //We passed n by only 1, so there's two more left
DoSomething();
}
现在我们在这里有n/3+2 个int 比较、n/3 个增量和n 个DoSomethig() 调用 = (1 2/3)*n。
我们节省了自己(1 1/3)*n 次操作。这将计算时间几乎减少了一半。
仅供参考,另一种巧妙的展开技术称为Duff 的设备。
但它是非常特定于编译器和语言实现的。有些语言实际上会更糟。