在C ++中初始化新分配的内存的最快方法是什么?

时间:2019-02-09 17:34:10

标签: c++ memory memory-management new-operator alloc

我正在尝试分配和使用100 MB的数据(size_t s = 100 * 1024 * 1024),并在C ++中测量了不同的方式:

没有初始化的原始分配:

// < 0.01 ms
auto p = new char[s]; 

C ++零初始化:

// 20 ms
auto p = new char[s](); 

手动归零:

// 20 ms
auto p = new char[s];
for (auto i = 0; i < s; ++i) 
    p[i] = 0;

这不是我的记忆限制,如再次写入记忆所证明的那样:

// 3 ms
std::memset(p, 0xFF, s);

我也尝试了std::mallocstd::calloc,但是它们表现出相同的行为。 calloc返回的内存初始化为零,但是如果我之后执行memset,则仍然需要20毫秒。

据我了解,未初始化的内存分配速度很快,因为它实际上并没有接触内存。仅当我访问它时,页面才分配给我的程序。设置100 MB的3毫秒对应于〜35GB / s,这可以确定。触发页面错误时,这20毫秒似乎是开销。

有趣的是,这似乎是计算开销。如果我使用多个线程对其进行初始化,它将变得更快:

// 6-10 ms
auto p = new char[s];
#pragma omp parallel for
for (auto i = 0; i < s; ++i) 
    p[i] = 0;

我的问题:是否有一种方法不仅可以分配内存,还可以立即分配所有页面,从而在访问它时不再出现页面错误?

如果可能,我想避免使用大页面。

(使用std::chrono::high_resolution_clock进行测量)

这是在装有Clang 7(-O2 -march=native)的台式机系统(5Ghz i9、3600 MHz DDR4,Linux Mint 19、4.15.0-45通用内核)上完成的,着眼于程序集,编译器不是问题。

编辑:这是一个简化的示例,在我的实际应用程序中,我需要使用一个不同于0的值来初始化它,但这根本不会改变时序。

0 个答案:

没有答案