2

我使用 tdm gcc 编译器来编译我的 winapi 项目,当我测试一些简单的 mandelbrot sse 代码 9 可能与其他项目一样但我没有测试所有内容时,5.1 生成更大的可执行文件 330kB 对 270kB(虽然我没有重新编译所有内容,只有热循环模块并与已编译的(在 4.7 中)链接)并且还通过较慢的代码 23.5 ms /frame agist 4.7 中的 20 ms

这很可怕..我能用它做什么?(其余设置等是相同的,我只是将编译器文件夹从一个重命名为另一个

我使用类似 c 的代码,但在 c++ 模式下编译

也许有人知道如何解决它?(通过解决我的意思是使 5.1 构建至少与 4.7 一样快,也希望可执行文件更小)

//编辑

ps 我做了快速测试

因为我可以在 51 中编译循环模块并在 47 中链接所有模块

编译循环 47 链接 47:大小 270k 速度 20 ms

编译循环 51 链接 51:大小 330k 速度 23.5 ms

编译循环 47 链接 51:大小 330k 速度 20 ms

编译循环 51 链接 47:大小 270k 速度 23.5 ms

它表明速度下降来自 51 中的编译,而大小膨胀来自链接 51

4

2 回答 2

0

我检查了程序集,它在生成的代码中显示了一些变化,虽然很小

4.7

__Z16mandelbrot_n_sseU8__vectorfS_i: 
    pushl        %ebp 
    movl        %esp, %ebp 
    andl        $-16, %esp 
    subl        $16, %esp 
    movl        8(%ebp), %ecx 
    movaps        %xmm0, (%esp) 
    testl        %ecx, %ecx 
    js        L12 
    xorps        %xmm0, %xmm0 
    xorl        %eax, %eax 
    movaps        %xmm0, %xmm2 
    movaps        %xmm0, %xmm4 
    jmp        L11 
    .p2align 4,,7 
L19: 
    mulps        %xmm4, %xmm2 
    addl        $1, %eax 
    subps        %xmm5, %xmm6 
    movaps        (%esp), %xmm4 
    cmpl        %eax, %ecx 
    addps        %xmm6, %xmm4 
    addps        %xmm2, %xmm2 
    addps        %xmm1, %xmm2 
    jl        L10 
L11: 
    movaps        %xmm4, %xmm6 
    movaps        %xmm2, %xmm5 
    movaps        LC5, %xmm7 
    mulps        %xmm4, %xmm6 
    mulps        %xmm2, %xmm5 
    movaps        %xmm6, %xmm3 
    addps        %xmm5, %xmm3 
    cmpltps        LC4, %xmm3 
    andps        %xmm3, %xmm7 
    movmskps        %xmm3, %edx 
    testl        %edx, %edx 
    addps        %xmm7, %xmm0 
    jne        L19 
L10: 
    cvtps2dq        %xmm0, %xmm0 
    leave 
    ret 
L12: 
    xorps        %xmm0, %xmm0 
    jmp        L10 
    .globl        __Z16mandelbrot_n_sseDv4_fS_i 

5.1

__Z16mandelbrot_n_sseDv4_fS_i: 
    pushl        %ebp 
    movl        %esp, %ebp 
    andl        $-16, %esp 
    subl        $16, %esp 
    movl        8(%ebp), %ecx 
    movaps        %xmm0, (%esp) 
    testl        %ecx, %ecx 
    js        L11 
    pxor        %xmm0, %xmm0 
    xorl        %edx, %edx 
    movaps        %xmm0, %xmm5 
    movaps        %xmm0, %xmm2 
    jmp        L10 
    .p2align 4,,10 
L18: 
    mulps        %xmm2, %xmm5 
    addl        $1, %edx 
    subps        %xmm6, %xmm4 
    cmpl        %edx, %ecx 
    addps        %xmm5, %xmm5 
    addps        (%esp), %xmm4 
    addps        %xmm1, %xmm5 
    jl        L9 
    movaps        %xmm4, %xmm2 
L10: 
    movaps        %xmm2, %xmm4 
    movaps        %xmm5, %xmm6 
    movaps        LC7, %xmm7 
    mulps        %xmm2, %xmm4 
    mulps        %xmm5, %xmm6 
    movaps        %xmm4, %xmm3 
    addps        %xmm6, %xmm3 
    cmpltps        LC6, %xmm3 
    andps        %xmm3, %xmm7 
    movmskps        %xmm3, %eax 
    testl        %eax, %eax 
    addps        %xmm7, %xmm0 
    jne        L18 
L9: 
    cvtps2dq        %xmm0, %xmm0 
    leave 
    ret 
L11: 
    pxor        %xmm0, %xmm0 
    jmp        L9 
    .section        .text.unlikely,"x" 
LCOLDE8: 
    .text 

看来 5.1 版本是倒霉的一个,它 cst 15% 减速

于 2015-09-29T06:51:08.173 回答
0

不同的 C++ 编译器版本使用不同的 C++ 引擎

  • 代码可能相同
  • 但发动机没有

C++ 引擎

  • 负责许多事情,例如:

    1. 内存管理(堆栈、堆、本地/全局/动态/静态/临时变量)
    2. 模板/类/结构/虚拟管理
    3. 指针管理
    4. 还有更多
  • 您可以将其视为操作系统(在某些情况下,它主要是 MCU 平台上的操作系统)

  • 或作为操作系统和您的应用程序之间的中介
  • 因此较新的版本通常会同时处理更多影响性能的事情
  • 这可以在文件大小上看到(链接器将引擎添加到您的可执行文件中)
  • 并且性能主要受到大量使用的影响:

    1. 动态内存分配/释放
    2. 班级
    3. 堆/堆栈垃圾

另一个可能的原因可能是链接库的版本

  • 如果您使用任何类型的库(如 std ...)
  • 然后较新的编译器/链接器可能包含它们的较新版本(根据其包含路径)
  • 这也会影响性能
  • 如果某些库无法识别较新版本的 GCC 定义
  • 他们可以切换到内部更慢/更安全的代码

如何将行为设置回旧样式

  • 如果需要,请使用较旧的编译器/链接器
  • 在较新的版本中,您可以使用较旧的引擎(但这可能会导致后面的问题)
  • 查找以下文件:

    crt0.o
    crtfv.o
    libc.a
    
  • 或类似的,并用旧版本替换它们

  • 但不建议这样做...
于 2015-09-10T09:34:20.117 回答