相关疑难解决方法(0)

为什么std :: pair比std :: tuple更快

这是测试代码.

元组测试:

using namespace std;

int main(){

    vector<tuple<int,int>> v;


    for (int var = 0; var < 100000000; ++var) {
        v.push_back(make_tuple(var, var));
    }
}
Run Code Online (Sandbox Code Playgroud)

配对测试:

#include <vector>

using namespace std;

int main(){

    vector<pair<int,int>> v;


    for (int var = 0; var < 100000000; ++var) {
        v.push_back(make_pair(var, var));
    }
}
Run Code Online (Sandbox Code Playgroud)

我通过Linux time命令进行了时间测量.结果是:

|       |   -O0   |    -O2   |
|:------|:-------:|:--------:|
| Pair  |   8.9 s |  1.60 s  |
| Tuple |  19.8 s |  1.96 s  |
Run Code Online (Sandbox Code Playgroud)

我想知道,为什么O0中的这两个数据结构之间存在如此大的差异,因为它们应该非常相似.02中只有一点不同.

为什么O0的差异如此之大,为什么会有任何差异呢?

编辑:

v.resize()的代码

对:

#include …
Run Code Online (Sandbox Code Playgroud)

performance c++11 stdtuple std-pair

42
推荐指数
2
解决办法
9898
查看次数

为什么 std::tuple 会破坏 C++ 中的小型结构调用约定优化?

C++ 具有小型结构调用约定优化,其中编译器在函数参数中传递小型结构与传递原始类型(例如,通过寄存器)一样有效。例如:

class MyInt { int n; public: MyInt(int x) : n(x){} };
void foo(int);
void foo(MyInt);
void bar1() { foo(1); }
void bar2() { foo(MyInt(1)); }
Run Code Online (Sandbox Code Playgroud)

bar1()bar2()生成几乎相同的汇编代码,除了分别调用foo(int)foo(MyInt)。特别是在 x86_64 上,它看起来像:

        mov     edi, 1
        jmp     foo(MyInt) ;tail-call optimization jmp instead of call ret
Run Code Online (Sandbox Code Playgroud)

但是如果我们测试std::tuple<int>,它会有所不同:

void foo(std::tuple<int>);
void bar3() { foo(std::tuple<int>(1)); }

struct MyIntTuple : std::tuple<int> { using std::tuple<int>::tuple; };
void foo(MyIntTuple);
void bar4() { foo(MyIntTuple(1)); }
Run Code Online (Sandbox Code Playgroud)

生成的汇编代码看起来完全不同,小尺寸的struct( std::tuple<int>)是通过指针传递的:

        sub     rsp, 24 …
Run Code Online (Sandbox Code Playgroud)

c++ x86 calling-convention c++11 stdtuple

29
推荐指数
2
解决办法
1292
查看次数

x86-64上的C++:何时传递结构/类并在寄存器中返回?

假设Linux上的x86-64 ABI,在C++中的什么条件下结构传递给寄存器中的函数而不是堆栈中的函数?他们在什么条件下返回登记册?课程的答案是否会改变?

如果它有助于简化答案,则可以假设单个参数/返回值而没有浮点值.

c++ assembly x86-64 abi

8
推荐指数
2
解决办法
1013
查看次数

为什么std :: pair &lt;long,long&gt;和std :: tuple &lt;long,long&gt;生成不同的代码

我期望std :: pair和std :: tuple具有类似的行为。但事实证明,与std :: pair相比,std :: tuple生成更差的asm代码。

https://gcc.godbolt.org/z/Ri4M8z-gcc 10.0.0每晚构建,-O3 -std=c++17
针对x86-64 System V ABI进行编译

#include <utility>

std::pair<long, long> test_pair() {
    return { 1, 2 };
}
Run Code Online (Sandbox Code Playgroud)
# returned in RDX:RAX
test_pair():
        mov     eax, 1
        mov     edx, 2
        ret
Run Code Online (Sandbox Code Playgroud)
#include <tuple>
std::tuple<long, long> test_tuple() {
    return { 1, 2 };
}
Run Code Online (Sandbox Code Playgroud)
# returned via hidden pointer, not packed into registers
test_tuple():
        mov     QWORD PTR [rdi], 2
        mov     QWORD PTR [rdi+8], 1
        mov     rax, rdi
        ret
Run Code Online (Sandbox Code Playgroud)

这两个函数都返回两个值。test_pair使用寄存器存储期望值;但是test_tuple将值存储在堆栈中,这似乎是未优化的。为什么这两个函数的行为不同?

c++ assembly x86-64 abi

5
推荐指数
0
解决办法
67
查看次数