繁体   English   中英

当局部变量复制到全局变量时,C ++ GCC优化速度会降低

[英]C++ GCC Optimization Speed slows down when local variable is copied to global variable

我有一个关于GCC优化标志及其工作原理的问题。

我有一段很长的代码,它利用了所有本地数组和变量。 在代码的最后,我将本地数组的内容复制到全局数组。 这是我的代码的一个非常简化的示例:

uint8_t globalArray[16]={0};
void func()
{ 
    unsigned char localArray[16]={0};
    for (int r=0; r<1000000; r++)
    {    
        **manipulate localArray with a lot of calculations**
    }
    memcpy(&globalArray,localArray,16);
}    

以下是三种不同场景中代码的近似速度:

  1. 没有 “-O3”优化:3.203s

  2. 随着 “-O3”优化:1.457s

  3. 使用 “-O3”优化并且没有最终的memcpy(&globalArray,localArray,16); 声明:0.015s

在不将本地数组复制到全局数组中的情况下,代码运行速度快了近100倍。 我知道全局数组存储在内存中,本地数组存储在寄存器中。 我的问题是:

  1. 为什么只将本地数组的16个元素复制到全局数组会导致执行速度慢100倍? 我在这个论坛和网上搜索过,我找不到这个特定场景的明确答案。

  2. 有什么办法可以在没有速度损失的情况下提取局部变量的内容吗?

提前感谢任何可以帮助我解决这个问题的人。

如果没有memcpy ,您的编译器可能会看到localArray永远不会被读取,因此它不需要在循环体中进行任何计算。

以此代码为例:

uint8_t globalArray[16]={0};
void func()
{ 
    unsigned char localArray[16]={0};
    for (int r=0; r<1000000; r++)
    {
        localArray[r%16] = r;
    }
    memcpy(&globalArray,localArray,16);
} 

带有-O3 Clang 3.7.1输出该组件:

func():                               # @func()
# BB#0:
        xorps   %xmm0, %xmm0
        movaps  %xmm0, -24(%rsp)
        #DEBUG_VALUE: r <- 0
        xorl    %eax, %eax
.LBB0_1:                                # =>This Inner Loop Header: Depth=1
        #DEBUG_VALUE: r <- 0
        movl    %eax, %ecx
        sarl    $31, %ecx
        shrl    $28, %ecx
        leal    (%rcx,%rax), %ecx
        andl    $-16, %ecx
        movl    %eax, %edx
        subl    %ecx, %edx
        movslq  %edx, %rcx
        movb    %al, -24(%rsp,%rcx)
        leal    1(%rax), %ecx
        #DEBUG_VALUE: r <- ECX
        movl    %ecx, %edx
        sarl    $31, %edx
        shrl    $28, %edx
        leal    1(%rax,%rdx), %edx
        andl    $-16, %edx
        negl    %edx
        leal    1(%rax,%rdx), %edx
        movslq  %edx, %rdx
        movb    %cl, -24(%rsp,%rdx)
        leal    2(%rax), %ecx
        movl    %ecx, %edx
        sarl    $31, %edx
        shrl    $28, %edx
        leal    2(%rax,%rdx), %edx
        andl    $-16, %edx
        negl    %edx
        leal    2(%rax,%rdx), %edx
        movslq  %edx, %rdx
        movb    %cl, -24(%rsp,%rdx)
        leal    3(%rax), %ecx
        movl    %ecx, %edx
        sarl    $31, %edx
        shrl    $28, %edx
        leal    3(%rax,%rdx), %edx
        andl    $-16, %edx
        negl    %edx
        leal    3(%rax,%rdx), %edx
        movslq  %edx, %rdx
        movb    %cl, -24(%rsp,%rdx)
        leal    4(%rax), %ecx
        movl    %ecx, %edx
        sarl    $31, %edx
        shrl    $28, %edx
        leal    4(%rax,%rdx), %edx
        andl    $-16, %edx
        negl    %edx
        leal    4(%rax,%rdx), %edx
        movslq  %edx, %rdx
        movb    %cl, -24(%rsp,%rdx)
        addl    $5, %eax
        cmpl    $1000000, %eax          # imm = 0xF4240
        jne     .LBB0_1
# BB#2:
        movaps  -24(%rsp), %xmm0
        movaps  %xmm0, globalArray(%rip)
        retq

对于没有memcpy的相同代码,它输出:

func():                               # @func()
# BB#0:
        #DEBUG_VALUE: r <- 0
        retq

即使你对装配一无所知,但很明显看到后者什么都不做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM