【问题标题】:gcc replaces loops with memcpy and memsetgcc 用 memcpy 和 memset 替换循环
【发布时间】:2018-04-10 08:22:42
【问题描述】:

我有以下简单的程序:

#define N 20
long c[N];
long a[N + N];

void f(void)
{
    long *s = c;
    long *p = a;
    while (p != a + N) *p++ = *s++;
    while (p != a + N + N) *p++ = 0;
}

我编译它:

/usr/gcc-arm-none-eabi-5_4-2016q3/bin/arm-none-eabi-gcc -mthumb -O3 -o main.o -c main.c

gcc 分别用memcpymemset 方便地替换循环:

00000000 <f>:
   0:   b570            push    {r4, r5, r6, lr}
   2:   4d07            ldr     r5, [pc, #28]   ; (20 <f+0x20>)
   4:   4c07            ldr     r4, [pc, #28]   ; (24 <f+0x24>)
   6:   002a            movs    r2, r5
   8:   4907            ldr     r1, [pc, #28]   ; (28 <f+0x28>)
   a:   0020            movs    r0, r4
   c:   f7ff fffe       bl      0 <memcpy>
  10:   1960            adds    r0, r4, r5
  12:   002a            movs    r2, r5
  14:   2100            movs    r1, #0
  16:   f7ff fffe       bl      0 <memset>
  1a:   bc70            pop     {r4, r5, r6}
  1c:   bc01            pop     {r0}
  1e:   4700            bx      r0

显然,gcc 很聪明,它决定库实现更有效,在每种特定情况下可能会或可能不会如此。我想知道如何避免这种行为,例如,当速度不重要并且不需要库调用时。

【问题讨论】:

  • 您已经明确告诉编译器使用-O3 命令行选项进行积极优化——这不是默认设置。如果您希望编译器不那么激进,请使用不同的优化设置,甚至不使用优化设置。
  • 这几乎是stackoverflow.com/a/33818680/1162141的复制品
  • 其实是这样。不幸的是,我无法使用“memcpy 循环”找到它。很多关于“什么更快?”的帖子谢谢。

标签: c gcc arm


【解决方案1】:

好的,搜索https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html 会显示以下选项:

-ftree-loop-distribute-patterns

对可以通过调用库生成的代码执行循环分布。此标志在 -O3 时默认启用。

指定-fno-tree-loop-distribute-patterns 可以避免接触标准库,而不会影响其他优化。

【讨论】:

  • -fno-tree-loop-distribute-patterns 不幸地不适用于 Clang。有谁知道用 Clang 解决同样问题的方法吗?
【解决方案2】:

您正在使用标志 -O3,它会强制编译器运行所有可用的优化方法,尝试使用较低的值,例如 -O2 或 -O。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-09
    • 1970-01-01
    • 2019-04-04
    • 2018-08-20
    相关资源
    最近更新 更多