2017-10-29 157 views
3

我有以下簡單的程序:GCC代替循環用的memcpy和memset

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

GCC方便地分別memcpymemset替換循環:

#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; 
} 

我編譯

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很聰明,並決定圖書館y實施更有效率,在每種特定情況下可能會也可能不會。我想知道如何避免這種行爲,例如,速度不重要,圖書館電話是不可取的。

+1

您明確告訴編譯器使用'-O3'命令行選項進行優化 - 這不是默認設置。如果您希望編譯器不那麼激進,請使用其他優化設置,或者甚至不進行優化設置。 – Peter

+0

這幾乎是https://stackoverflow.com/a/33818680/1162141 – technosaurus

+0

的副本。實際上,它是。不幸的是,我找不到'memcpy loop'。很多關於「什麼更快?」的帖子謝謝。 –

回答

0

您正在使用標誌-O3,它會強制編譯器運行所有可用的優化方法,嘗試使用較低的值,例如-O2或-O。

2

好了,通過https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html搜索顯示了以下選項:

-ftree-loop-distribute-patterns 

Perform loop distribution of patterns that can be code generated with calls to a library. This flag is enabled by default at -O3. 

指定-fno-tree-loop-distribute-patterns避免接觸標準庫中似乎沒有影響其他的優化。