MSVC:为什么调用静态函数比调用实例方法生成更多的汇编代码?

MSVC: why calling a static function generates more assembly code than calling an instance method?

提问人:Laurent 提问时间:3/14/2023 最后编辑:Laurent 更新时间:3/14/2023 访问量:101

问:

在反汇编应用程序时,我注意到与实例方法相比,在调用静态方法时,MSVC 生成的程序集操作码更多。即使两个函数相同(因此实例方法不使用 )。this

代码示例:

struct matrix4
{
    float m[16];
    static const matrix4 identity;

    static matrix4 translation1(float x);
    matrix4 translation2(float x) const;
};

func(matrix4::translation1(0));
func(matrix4::identity.translation2(0));

生成的代码将如下所示:

        call    static matrix4 matrix4::translation1(float)       ; matrix4::translation1
        push    16                                  ; 00000010H
        mov     esi, eax
        lea     edi, DWORD PTR $T2[ebp]
        pop     ecx
        lea     eax, DWORD PTR $T2[ebp]
        rep movsd
        push    eax
        call    void func(matrix4 const &)                ; func

[...]

        mov     ecx, OFFSET static matrix4 const matrix4::identity      ; matrix4::identity
        call    matrix4 matrix4::translation2(float)const       ; matrix4::translation2
        push    eax
        call    void func(matrix4 const &)                ; func

对于我的应用程序,我关心生成的文件大小。看起来我应该用实例方法替换我所有的静态方法,这对我来说似乎真的很惊讶。我宁愿避免这种情况,因为这意味着要更改大量代码。我错过了什么吗?

重现:https://godbolt.org/z/o3x5vKGdK(比较 block1 和 block2)

我注意到其他编译器标志(有和没有/Os)也有类似的问题。无论方法是否内联,都会发生同样的情况。

Clang 似乎没有这种行为。如果这是 MSVC 优化错误,是否有简单的解决方法?

(当我将代码从 Visual Studio 2010 升级到更新的 VS 版本时,我注意到了这个问题。VS2010 正在生成一个较小的可执行文件。

C 可视化 C++ 编译器 返回值优化

评论

1赞 Remy Lebeau 3/14/2023
您显示的代码不会编译(没有 named 的成员),并且生成的程序集与显示的代码也不匹配(并且不采用参数)。您展示的代码与 Godbolt 上的演示代码不匹配。staticmatrix4identitytranslation1()translation2()float
0赞 Laurent 3/14/2023
对不起,我稍微简化了代码。它现在已经更新了,但这应该不会有什么不同(参见 godbolt 链接作为参考)。
2赞 Remy Lebeau 3/14/2023
您可以考虑使用该标志关闭缓冲区安全检查,这将省略一些额外的汇编代码。但是您仍然会看到生成的汇编比 少,因此显然在幕后正在进行一些其他优化。/GS-func(matrix4::identity.translation2(0));func(matrix4::translation1(0));
1赞 Peter Cordes 3/14/2023
您正在制作旧版 32 位代码,因此成员函数的调用约定不同(ECX 中的 arg)与。 它看起来像。此外,非静态函数仅使用指向 的指针进行调用,而不会在堆栈位置之间复制返回值。如果您想要高效的代码,通常 MSVC 不是最佳选择。thiscallthisstdcalltranslation2()static matrix4::identity
0赞 user253751 3/14/2023
我不确定究是什么在这里造成了差异(似乎正在将矩阵复制到一个新变量中?),但是如果您制作静态函数呢?__fastcall

答: 暂无答案