我最近开始使用 C++14 而不是 C++11 对我的 C++ 代码库进行现代化改造。
在用 C++14 中的 std::make_unique
替换一次出现的 std::unique_ptr.reset(new ...)
后,我意识到我的测试套件(由大约 30 个 C++ 测试程序组成)运行速度慢了大约 50%。
旧的 C++11 代码(快速):
class Foo
{
public:
Foo(size_t size)
{
array.reset(new char[size]);
}
private:
std::unique_ptr<char[]> array;
};
新的 C++14 代码(慢):
class Foo
{
public:
Foo(size_t size)
{
array = std::make_unique<char[]>(size);
}
private:
std::unique_ptr<char[]> array;
};
使用带有 std::make_unique
的 C++14 代码时,GCC 和 Clang 的运行速度要慢得多。当我使用 valgrind 测试这两个版本时,它报告 C++11 和 C++14 代码使用相同数量的分配和相同数量的分配内存,并且没有内存泄漏。
当我查看上面生成的测试程序程序集时,我怀疑使用 std::make_unique
的 C++14 版本会在使用 memset 分配后重置内存。 C++11版本不这样做:
C++11 程序集(GCC 7.4、x64)
main:
sub rsp, 8
movsx rdi, edi
call operator new[](unsigned long)
mov rdi, rax
call operator delete[](void*)
xor eax, eax
add rsp, 8
ret
C++14 程序集(GCC 7.4、x64)
main:
push rbx
movsx rbx, edi
mov rdi, rbx
call operator new[](unsigned long)
mov rcx, rax
mov rax, rbx
sub rax, 1
js .L2
lea rax, [rbx-2]
mov edx, 1
mov rdi, rcx
cmp rax, -1
cmovge rdx, rbx
xor esi, esi
call memset
mov rcx, rax
.L2:
mov rdi, rcx
call operator delete[](void*)
xor eax, eax
pop rbx
ret
问题:
初始化内存是 std::make_unique
的已知特性吗?如果不是,还有什么可以解释我遇到的性能下降?
最佳答案
Is initializing memory a known feature of
std::make_unique
?
这取决于您所说的“已知”是什么意思。但是,是的,这就是您的案例之间的区别。来自 cppreference , make_unique<T>(size)
调用:
unique_ptr<T>(new typename std::remove_extent<T>::type[size]()) // ~~~~
就是这样 specified .
new char[size]
分配内存并默认初始化它。 new char[size]()
分配内存并对其进行值初始化,在 char
的情况下进行零初始化.默认情况下,标准库中的很多东西都会值初始化而不是默认初始化。
同样,make_unique<T>()
new T()
而不是 new T
... make_unique<char>()
给你0,new char
给你一个不确定的值。
作为一个类似的例子,如果我想要一个 vector<char>
调整为给定大小的 未初始化 缓冲区(立即被其他东西填充),我必须使用我自己的分配器或使用不是 char
的类型这与它的初始化有关。
C++20 将引入新的辅助函数来缓解这个问题,由 P11020R1 提供:
-
make_unique_default_init
-
make_shared_default_init
-
allocate_shared_default_init
鉴于 make_unique<T>()
会做new T()
,这些都可以new T
.也就是说,没有额外的归零。在 OP 的特定情况下,std::make_unique_default_init<char[]>(size)
就是你想要的。
关于c++ - std::make_unique 导致大幅减速?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49818536/