【问题标题】:calloc v/s malloc and time efficiencycalloc vs malloc 和时间效率
【发布时间】:2011-02-06 00:32:15
【问题描述】:

我感兴趣地阅读了C difference between malloc and calloc 的帖子。我在我的代码中使用了 malloc,想知道使用 calloc 会有什么不同。

我现在使用 malloc 的(伪)代码:

场景 1

int main()
{  
   allocate large arrays with malloc

   INITIALIZE ALL ARRAY ELEMENTS TO ZERO

   for loop //say 1000 times
    do something and write results to arrays
   end for loop

   FREE ARRAYS with free command

} //end main

如果我使用 calloc 而不是 malloc,那么我将拥有:

场景2

int main()
{  

   for loop //say 1000 times
    ALLOCATION OF ARRAYS WITH CALLOC 

    do something and write results to arrays

    FREE ARRAYS with free command

   end for loop


} //end main

我有三个问题:

  1. 如果数组非常大,哪种方案效率更高?

  2. 如果数组非常大,哪种方案更省时?

  3. 在这两种情况下,我只是写入数组,因为对于 for 循环中的任何给定迭代,我从第一个元素到最后一个元素按顺序写入每个数组。重要的问题:如果我在场景 1 中使用 malloc,那么是否有必要将元素初始化为零?用 malloc 说我有数组 z = [garbage1,garbage2,garbage 3]。对于每次迭代,我按顺序编写元素,即在第一次迭代中我得到 z =[some_result,garbage2,garbage3],在第二次迭代中我在第一次迭代中得到 z =[some_result, another_result,garbage3] 等等on,那么我需要在 malloc 之后专门初始化我的数组吗?

【问题讨论】:

  • 是的,这就是为什么我提到我阅读了另一篇文章。我想在这里更具体一点。
  • 您自己测量过吗?你的机器上的结果是什么?
  • 还没有。如果有差异我会回来写的。
  • 这是一个相关(稍后)的问题,它探讨了为什么 calloc 可以比 malloc+memset 快得多(10 倍)。 stackoverflow.com/questions/2688466

标签: c optimization malloc calloc


【解决方案1】:

假设在您的两个示例中初始化的内存总量相同,使用 calloc() 分配内存可能比使用 malloc() 分配内存然后在单独的步骤中将它们清零更快,尤其是在malloc() 情况下,您可以通过在循环中迭代它们来单独将元素归零。 malloc() 后跟 memset() 可能与 calloc() 一样快。

如果您在实际将计算结果存储在其中之前不关心数组元素是垃圾,则无需在malloc() 之后实际初始化您的数组。

【讨论】:

  • 太棒了。一个问题:memset() 是导致初始化为零还是NULL?
  • 我正在使用 C。我认为 memset() 用于 C++,在 C 中不可用。
  • @yCa:memset 在 C++ 和 C 中都可用。NULL 是一个常量,旨在用于初始化指针,并将其用于其他事情(例如当需要 int 值时)是错误的,即使它可能有效。
  • 我不敢说 malloc/memset 序列与 calloc 一样快。这取决于 libc 的实现。如果操作系统提供的内存已经初始化为零怎么办? calloc 实现可能知道这一点,因此跳过将内存归零。 malloc/memset 序列中的 memset 将是多余的,而且肯定不如 calloc 快。例如在 Linux 下,当请求大内存块并且内存已被 Linux 清零时,使用 mmap() 系统调用。
  • @Fabian: 在mmap 的时候内存没有“已经归零”。相反,它是对通用零页的纯粹未触及的写时复制引用。它将在第一次写入时被实例化为用零填充的物理内存。因此,使用calloc 将零初始化内存的成本从分配时间推迟到首次写入时间。这在实时应用程序中非常有用,其中单个大 memset 可能会导致过多的延迟,但分散在许多后续本地访问的成本是可以接受的。
【解决方案2】:

对于 1 和 2,两者都做同样的事情:分配和归零,然后使用数组。

对于 3,如果您不需要先将数组归零,则无需进行归零,并且不进行归零会更快。

calloc 的归零有可能比您编写的代码更有效,但与程序所做的其他工作相比,这种差异会很小。 calloc 真正节省的地方是不必自己编写代码。

【讨论】:

  • 感谢您提供有趣的 cmets。
【解决方案3】:

callocmemset 方法应该大致相同,并且可能比自己归零快一些。

无论如何,这都与您在主循环中所做的事情有关,可能要大几个数量级。

【讨论】:

  • 谢谢。循环内发生的事情可能会更耗时。
【解决方案4】:

您在 3. 中陈述的观点似乎表明一个案例或不必要的初始化。这在速度方面非常糟糕,不仅浪费了时间,而且还因此发生了很多缓存驱逐。

执行memset()bzero()(无论如何都由calloc() 调用)是使大部分缓存无效的好方法。除非您确定不会覆盖所有内容但可以读取尚未写入的缓冲区部分(好像 0 是可接受的默认值),否则不要这样做。如果您无论如何都要重写所有内容,请不要不必要地初始化您的内存。

不必要的内存写入不仅会破坏您的应用程序性能,还会破坏与其共享同一 CPU 的所有应用程序的性能。

【讨论】:

  • 感谢您提供有趣的意见。
【解决方案5】:

malloc 比 Calloc 快,因为原因是 malloc 从操作系统返回内存。但是,当您调用 Calloc 时,它会从内核或操作系统获取内存,并以零初始化,然后返回给您。 所以,初始化需要时间。这就是为什么 malloc 比 Calloc 快的原因

【讨论】:

    【解决方案6】:

    我不知道 linux。但是在 Windows 上,有一种叫做零页面线程的东西...... calloc 使用那些已经初始化为零的页面。 malloc 和 calloc 速度没有区别。

    【讨论】:

      【解决方案7】:

      malloccalloc 不同有两个原因

      1. malloc 采用一个参数,而 calloc 采用两个参数

      2. malloc 比 calloc 快,原因是 malloc 将一维数组处理为指针格式,而 calloc 采用二维数组,在处理之前先转换为一维数组,然后再转换为指针格式。

      我认为,这就是为什么 malloc 处理速度比 calloc 快的原因

      【讨论】:

        猜你喜欢
        • 2012-03-02
        • 2018-06-12
        • 2013-11-17
        • 2020-03-22
        • 2010-12-05
        • 2020-04-08
        • 2013-06-06
        • 2018-05-28
        相关资源
        最近更新 更多