首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何让MSVC编译器优化多步POD初始化?

如何让MSVC编译器优化多步POD初始化?
EN

Stack Overflow用户
提问于 2018-06-07 06:58:59
回答 1查看 94关注 0票数 0

我制作了以下示例代码:

#include <vector>

struct POD {
    int a;
    int b;
    int c;

    inline static POD make_pod_with_default()
    {
        POD p{ 41, 51, 61 };
        return p;
    }

    inline void change_pod_a(POD &p, int a) {
        p.a = a;
    }

    inline void change_pod_b(POD &p, int b) {
        p.b = b;
    }

    static POD make_pod_with_a(int a) {
        POD p = make_pod_with_default();
        p.change_pod_a(p, a);
        return p;
    }

    static POD make_pod_with_b(int a) {
        POD p = make_pod_with_default();
        p.change_pod_b(p, a);
        return p;
    }
};

int main()
{
    std::vector<POD> vec{};
    vec.reserve(2);
    vec.push_back(POD::make_pod_with_a(71));
    vec.push_back(POD::make_pod_with_b(81));
    return vec[0].a + vec[0].b + vec[0].c + vec[1].a + vec[1].b + vec[1].c;
}

在编译后的汇编代码中,我们可以看到为第一个vec.push_back(...)生成了以下指令呼叫:

...
mov      DWORD PTR $T2[esp+32], 41 ; 00000029H
...
mov      DWORD PTR $T2[esp+36], 51 ; 00000033H
...
mov      DWORD PTR $T5[esp+32], 71 ; 00000047H
...
mov      DWORD PTR $T6[esp+44], 61 ; 0000003dH
...

有一个移动到esp+32的71,但移动到esp+32的41仍然在那里,是无用的!我怎样才能为MSVC编写代码来实现这种优化,MSVC能做到这一点吗?

GCC和CLANG都给出了更优化的版本,但CLANG以一种非常干净和合乎逻辑的方式以很大的优势击败了对手,几乎没有开销:

CLANG生成的代码:

main: # @main
push rax
mov edi, 24
call operator new(unsigned long)
mov rdi, rax
call operator delete(void*)
mov eax, 366
pop rcx
ret

在编译时,所有操作都是按照71 + 51 + 61 + 41 + 81 + 61 = 366完成的!我必须承认,看到我的程序在编译时被计算,并且仍然在程序集中抛出对vec.reserve()的调用是很痛苦的……但到目前为止,CLANG仍然占据了上风!来吧,MSVC,这不是一个易失性的向量。

EN

回答 1

Stack Overflow用户

发布于 2018-06-07 08:19:05

如果您将您的方法转换为constexpr,您可能会这样做:

constexpr POD step_one()
{
    POD p{2, 5, 11};
    p.b = 3;
    return p;
}

constexpr void step_two(POD &p)
{
    p.c = 5;
}

constexpr POD make_pod(){
    POD p = step_one();
    step_two(p);
    return p;
}

POD make_pod_final()
{
    constexpr POD res = make_pod();
    return res;
}

结果是:

make_pod_final PROC
    mov      eax, DWORD PTR $T1[esp-4]
    mov      DWORD PTR [eax], 2
    mov      DWORD PTR [eax+4], 3
    mov      DWORD PTR [eax+8], 5
    ret      0

Demo

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50730768

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档