在 C++ 中使用 std::vector 进行逃逸分析
Escape Analysis with std::vector in C++
我想知道 Clang 或 GCC 中是否有任何优化选项可用于对 C++ 中的 std::vector
进行逃逸分析。
由于下面示例中的 std::vector<int>
不需要在堆或堆栈中分配 v
的实际数据。编译器实际上可以在堆栈上分配 v.data()
以获得更好的性能。
假设Clang/GCC不做逃逸分析,有什么特别的动机不使用逃逸分析吗?
假设Clang/GCC做了逃逸分析,为什么v.data()
和&x
的值如此不同?
#include<cstdio>
#include<vector>
int main() {
int x = 0;
std::vector<int> v(3, 0);
std::printf("&x: %p\n", &x);
//std::printf("&v: %p\n", &v); // we intentionally don't print the pointer to v here.
std::printf("v.data(): %p\n", v.data());
return x + v[0]; // we want compiler not to optimize everything out
}
预期结果
&x: <some address>
v.data(): <some address> + 4
Clang 和 GCC 的实际结果
[*****@localhost test]$ g++ test.cc -O3
[khanh@localhost test]$ ./a.out
&x: 0x7ffe2af5a59c
v.data(): 0xadde70
[*****@localhost test]$ clang++ test.cc -O3
[*****@localhost test]$ ./a.out
&x: 0x7fff66ce1ab4
v.data(): 0xfeee70
谢谢!
Clang编译器存在逃逸分析
示例代码:来自@geza https://godbolt.org/z/N1GLUI
int fn(int a, int b, int c) {
int *t = new int[3];
t[0] = a;
t[1] = b;
t[2] = c;
int r = t[0]+t[1]+t[2];
delete[] t;
return r;
}
海湾合作委员会
fn(int, int, int):
push r12
mov r12d, edx
push rbp
mov ebp, esi
push rbx
mov ebx, edi
mov edi, 12
call operator new[](unsigned long)
mov DWORD PTR [rax], ebx
add ebx, ebp
mov rdi, rax
mov DWORD PTR [rax+4], ebp
mov DWORD PTR [rax+8], r12d
add r12d, ebx
call operator delete[](void*)
mov eax, r12d
pop rbx
pop rbp
pop r12
ret
铿锵
fn(int, int, int): # @fn(int, int, int)
lea eax, [rdi + rsi]
add eax, edx
ret
我想知道 Clang 或 GCC 中是否有任何优化选项可用于对 C++ 中的 std::vector
进行逃逸分析。
由于下面示例中的 std::vector<int>
不需要在堆或堆栈中分配 v
的实际数据。编译器实际上可以在堆栈上分配 v.data()
以获得更好的性能。
假设Clang/GCC不做逃逸分析,有什么特别的动机不使用逃逸分析吗?
假设Clang/GCC做了逃逸分析,为什么
v.data()
和&x
的值如此不同?
#include<cstdio>
#include<vector>
int main() {
int x = 0;
std::vector<int> v(3, 0);
std::printf("&x: %p\n", &x);
//std::printf("&v: %p\n", &v); // we intentionally don't print the pointer to v here.
std::printf("v.data(): %p\n", v.data());
return x + v[0]; // we want compiler not to optimize everything out
}
预期结果
&x: <some address>
v.data(): <some address> + 4
Clang 和 GCC 的实际结果
[*****@localhost test]$ g++ test.cc -O3
[khanh@localhost test]$ ./a.out
&x: 0x7ffe2af5a59c
v.data(): 0xadde70
[*****@localhost test]$ clang++ test.cc -O3
[*****@localhost test]$ ./a.out
&x: 0x7fff66ce1ab4
v.data(): 0xfeee70
谢谢!
Clang编译器存在逃逸分析
示例代码:来自@geza https://godbolt.org/z/N1GLUI
int fn(int a, int b, int c) {
int *t = new int[3];
t[0] = a;
t[1] = b;
t[2] = c;
int r = t[0]+t[1]+t[2];
delete[] t;
return r;
}
海湾合作委员会
fn(int, int, int):
push r12
mov r12d, edx
push rbp
mov ebp, esi
push rbx
mov ebx, edi
mov edi, 12
call operator new[](unsigned long)
mov DWORD PTR [rax], ebx
add ebx, ebp
mov rdi, rax
mov DWORD PTR [rax+4], ebp
mov DWORD PTR [rax+8], r12d
add r12d, ebx
call operator delete[](void*)
mov eax, r12d
pop rbx
pop rbp
pop r12
ret
铿锵
fn(int, int, int): # @fn(int, int, int)
lea eax, [rdi + rsi]
add eax, edx
ret