sho*_*nex 8 c optimization gcc
知道循环将经历的迭代次数允许编译器进行一些优化.考虑下面的两个循环:
未知的迭代次数:
static void bitreverse(vbuf_desc * vbuf)
{
unsigned int idx = 0;
unsigned char * img = vbuf->usrptr;
while(idx < vbuf->bytesused) {
img[idx] = bitrev[img[idx]];
idx++;
}
}
Run Code Online (Sandbox Code Playgroud)
已知的迭代计数
static void bitreverse(vbuf_desc * vbuf)
{
unsigned int idx = 0;
unsigned char * img = vbuf->usrptr;
while(idx < 1280*400) {
img[idx] = bitrev[img[idx]];
idx++;
}
}
Run Code Online (Sandbox Code Playgroud)
第二个版本将编译为更快的代码,因为它将被展开两次(在ARM上使用gcc 4.6.3和至少-O2).有没有办法对gcc在优化时考虑的循环计数进行断言?
有hot属性上的功能给予提示编译器有关热点:http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html.在你的功能之前刚刚abb:
static void bitreverse(vbuf_desc * vbuf) __attribute__ ((pure));
Run Code Online (Sandbox Code Playgroud)
这里有关于' hot'来自gcc 的文档:
hot函数的hot属性用于通知编译器函数是已编译程序的热点.该功能进行了更积极的优化,并且在许多目标上,它被放置在文本部分的特殊子部分中,因此所有热门功能都紧密地联系在一起,从而改善了局部性.当配置文件反馈可用时,通过-fprofile-use,将自动检测热门功能,并忽略此属性.
函数的热属性未在4.3之前的GCC版本中实现.
标签上的hot属性用于通知编译器标签后面的路径比未注释的路径更可能.此属性用于无法使用__builtin_expect的情况,例如计算goto或asm goto.
标签上的hot属性未在4.8之前的GCC版本中实现.
您也可以尝试在您的周围添加__builtin_expect idx < vbuf->bytesused- 这将暗示在大多数情况下表达式为真.
在这两种情况下,我都不确定您的循环是否会被优化.
或者,您可以尝试配置文件引导优化.构建配置文件生成版本的程序-fprofile-generate; 在目标上运行它,将配置文件数据复制到构建主机并使用重建-fprofile-use.这将为编译器提供大量信息.
在一些编译器中(不在GCC中)有循环编译指示,包括" #pragma loop count (N)"和" #pragma unroll (M)",例如在英特尔 ; 在IBM注册 ; 在MSVC中矢量化pragma
ARM编译器(armcc)也有一些循环编译指示:unroll(n)(通过1):
循环展开:http://infocenter.arm.com/help/index.jsp ? topic =/com.arm.doc.dui0348b/CJACACFE.html 和http://infocenter.arm.com/help/index.jsp?主题=/com.arm.doc.dui0348b/CJAHJDAB.html
和__promise内在:
使用__promise来改进矢量化
__promise(expr)内在函数是编译器对给定表达式非零的承诺.这使编译器能够通过优化远离代码来改进矢量化,这些代码基于您所做的承诺是多余的.示例3.21的反汇编输出显示了__promise产生的差异,通过删除标量修复循环将反汇编减少为简单的矢量化循环.
例3.21.使用__promise(expr)来改进矢量化代码
void f(int *x, int n)
{
int i;
__promise((n > 0) && ((n&7)==0));
for (i=0; i<n;i++) x[i]++;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3795 次 |
| 最近记录: |