将现有数组归零的最快方法是啥?

Posted

技术标签:

【中文标题】将现有数组归零的最快方法是啥?【英文标题】:What is the fastest way to zero an existing array?将现有数组归零的最快方法是什么? 【发布时间】:2012-01-03 19:34:50 【问题描述】:

我有一个现有的一维数组,memset 是最快的归零方法吗?

【问题讨论】:

相关:***.com/questions/8528590/… 是的,它是迄今为止最快的。所有的内存...家伙都很快,因为他们知道如何设置目标字以及目标字节。也就是说,例如,当要将四个零字节移动到一个内存字中时,memset 会一次性清除内存位置。作为奖励,memset 和 memmove 以及 memcopy 是可移植的。 memset 会将所有位设置为 0,但这可能并不总是您想要发生的。你关心便携性吗?数组中有什么? 可能与以下内容重复:***.com/questions/1373369/… 仅当您无法确定它是否已经归零时。如果可以确定,memset 并不是最快的。 :) 【参考方案1】:

最快的......可能是的。 几乎可以肯定的越野车!

这主要取决于实现、平台和...数组包含的类型。

在 C++ 中,当定义一个变量时,它的构造函数会被调用。定义数组时,会调用数组中所有元素的构造函数。

只有在已知数组类型具有可以用全零表示的初始状态并且默认构造函数不执行任何操作的情况下,才可以认为擦除内存是“好的”。

一般对于内置类型是正确的,但对于其他类型也是错误的。

最安全的方法是为元素分配一个默认的初始化临时值。

template<class T, size_t N>
void reset(T* v)

    for(size_t i=0; i<N; ++i) 
        v[i] = T();

请注意,如果 T 是 char,则函数实例化并完全转换为 memset。所以速度是一样的,不多不少。

【讨论】:

平台:Windows,类型:float,大小:1e6。此外,运行速度是第一要务,甚至比安全更重要。 @Shilbli:可能是上面的模板可以更好:memset 设置字节。我的函数设置浮点数,它们具有与处理器字相同的大小。如果编译器具有良好的优化(在寄存器中调整 i 并将 T() 保持为外部循环常量)可能比非专用 memset 更快!但这主要取决于编译器,而不是库。 这可以通过标准库使用std::fill_n来完成。 @Blastfurnace:有一点不同:std::fill_n 将大小作为运行时参数,这里是编译时常量。编译器可以在这种情况下进行更多优化,例如通过展开或并行化循环。【参考方案2】:

这是不可能知道的,因为它是特定于实现的。不过一般来说,memset 将是最快的,因为库实现者已经花费了大量时间优化它以使其非常快,有时编译器可以对其进行优化,而这在手动实现中无法完成,因为它知道memset含义

【讨论】:

如果支持的话,更不用说内在函数了。 对于非常大的阵列,calloc 可能会更快,利用目标机器的存储管理功能。但是如果不深入了解混乱的内部结构,就无法知道。 @HotLicks 他确实说过“现有数组” 是的,但是在 C/C++ 中,“现有数组”的定义相当广泛。 @EmilioGaravaglia -- 一个称职的 memset 开发者会知道机器的缓存行大小,并且可能能够利用“清除缓存行”操作等。一般是前端将以“常规”方式清除到缓存(甚至页面)边界,然后将使用特定于硬件的清除函数进行循环,直到到达尾随缓存/页面边界,此时为“常规”清除简历。

以上是关于将现有数组归零的最快方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

将数组中的低值归零的最快方法?

将向量归零的最快方法<vector<bool>>

在现有项目中保存大型类数组的最佳和最快方法是啥?领域不工作

检查字节数组是不是全为零的最快方法

将数组中的所有元素初始化为 NaN 的最快方法是啥?

检查内存是不是清零的最快方法