gpt4 book ai didi

在 Linux/x86-84 上传递大对象的 C++ 调用约定

转载 作者:行者123 更新时间:2023-12-03 09:46:00 25 4
gpt4 key购买 nike

我试图了解在 C++/Linux/x86-64 平台中按值传递对象作为函数参数的开销。
我用于探索的实验代码发布在下面和godbolt.org上:https://godbolt.org/z/r9Yfv4
假设函数是一元的。我观察到的是:

  • 如果参数对象的大小为 8 字节,则将其放入 RDI。
  • 如果参数大小为 16 字节(每 8 字节包含两个子对象),则将这两个子对象放入 RDI 和 RSI。
  • 如果参数大于 16 字节,它将通过堆栈传递。

  • 我只考虑整型和指针以及这些基本类型的组合类型。我知道传递 float / double 是不同的。 std::function尺寸是 32 字节(GCC/Linux 实现,长 + 长 + 指针 + 指针 = 32 字节。)。所以路过 std::function按值应该看起来像 pass struct Person4在我的代码中定义。但是输出程序集显示通过 std::function和pass很不一样 struct Person3 .看起来 std::function 是通过指针传递的,对吗?为什么会有这样的差异?
    #include <functional>

    struct Person0 {
    long name;
    };

    long GetName(Person0 p) {
    return p.name;
    }

    struct Person1 {
    long name;
    long age;
    };

    long GetName(Person1 p) {
    return p.name;
    }

    struct Person2 {
    long name;
    long age;
    long height;
    };

    long GetName(Person2 p) {
    return p.name;
    }

    struct Person3 {
    long name;
    long age;
    long height;
    long weight;
    };

    long GetName(Person3 p) {
    return p.name + sizeof(p);
    }

    long Invoke(std::function<long(long)> f) {
    return f(20) + sizeof(f);
    }


    int main() {
    Person3 p;
    p.name = 13;
    p.age = 23;
    p.height = 33;
    p.weight = 43;
    long n = GetName(p);

    std::function<long(long)> ff;
    Invoke(ff);
    return 0;
    }

    最佳答案

    您要阅读的文档是 System V ABI for x86-64 ,特别是第 3.2.3 节
    «参数传递»
    大于 32 字节的结构始终在堆栈上。
    对于 <= 32 字节的结构,有一些逻辑在进行:
    Paramater Passing Rules
    合并后清理表明,如果大小大于 2 个 eighbytes(16 字节),并且第一个参数不是 SSE,或者任何其他参数都不是 SSEUP,则整个聚合被归类为 MEMORY(堆栈)。
    关于std::function的使用,最后一条规则可以解释它:

    1. If a C++ object has either a non-trivial copy constructor or a non-trivial destructor, it is passed by invisible reference (theobject is replaced in the parameter list by a pointer that has classINTEGER)

    关于在 Linux/x86-84 上传递大对象的 C++ 调用约定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65838379/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com