【问题标题】:malloc in C++ for performanceC++ 中的 malloc 以提高性能
【发布时间】:2021-07-19 11:56:13
【问题描述】:

我正在优化以性能为优先的程序的计算密集型部分。

目前我正在使用 std::array 来处理无法立即初始化的各种类型的数据和缓存。为了性能,我想为缓存分配内存没有默认初始化元素,这样我可以在计算它们后用适当的值初始化它们。我能想到的唯一方法是使用 malloc。是否有任何“更清洁”的方式来实现这一点,这是在 C++ 中合理使用 malloc 的吗?

我知道“永远不要使用 malloc/new[]”的常见建议。显然需要基于测量进行优化。这不是过早的优化。这部分代码在每个线程上每秒调用约 250 万次,每次调用应在 1000 纳秒内运行。

【问题讨论】:

  • 最佳选择是在到达这部分代码之前分配一次,并完全避免在这个关键部分内进行分配/重新分配。就此而言,mallocnew 没有任何问题。不同之处在于malloc 对对象构造一无所知。如果您只是分配一个“普通旧类型”块,那么 malloc 就可以了。如果您分配的内容依赖于构造函数来进一步分配等,那么new 是您的选择。是的,如果您不能预先分配/构造其他东西,这将是对 malloc 的有效使用。
  • 在优化之前,您现在每秒是否在堆上分配 std::array 250 万次?

标签: c++ performance optimization memory malloc


【解决方案1】:

分配一个足够大的字节数组,以容纳您最终要构造的最大元素数。然后,只要您想在数组内的给定字节偏移处构造对象,就可以使用placement-new

您也可以使用std::aligned_storage 作为数组元素类型,而不是使用原始字节。链接的文档甚至提供了这种精确技术的示例。

【讨论】:

    【解决方案2】:

    这里是如何干净地分配 std::array 而不初始化它并且不使用 C 风格的 API 或像 aligned_storage 这样的低级 API。

    #include <memory>
    #include <array>
    
    template <class T> struct uninit : public T
    {
        uninit() {} // do not omit, do not make = default.
    };
    
    using myarray = std::array<int, 1337>;
    using myarray_uninit = uninit<myarray>;
    
    std::unique_ptr<myarray> allocate_myarray()
    {
        return std::make_unique<myarray_uninit>();
    }
    

    Live demo

    这个特定的答案与在堆上分配东西的性能与在堆上分配东西的性能无关。

    【讨论】:

    • 你能解释一下为什么 uninit 结构不初始化它派生的数组的元素吗?为什么没有初始化列表的空构造函数会阻止基类调用其构造函数,这不应该与隐式生成的构造函数相同吗?来自标准:“隐式定义的默认构造函数执行类的一组初始化,这些初始化将由用户编写的该类的默认构造函数执行,没有 ctor-initializer (12.6.2) 和空的复合语句。 "
    • 它不会初始化元素,因为基类没有显式构造函数,所以它是默认初始化的。但是,如果您默认或省略 ctor,则整个类将成为 POD 并将被零初始化。有时我只是喜欢 C++。
    • 谢谢,再问一个问题:根据标准,未在 ctor-list 初始化程序中初始化的成员是默认初始化的。那么基本默认值的隐式默认构造函数不应该初始化它的所有成员,因为它没有 ctor-list 初始化程序吗?这意味着作为基类一部分的 c 样式数组将被默认初始化,但标准还说“默认初始化数组类型意味着每个元素都是默认初始化的”。这将是我们试图避免的结果。你能指出我的逻辑缺陷在哪里吗?
    • 不,我们试图避免零初始化,而不是默认初始化。
    • 好的,我明白你在说什么。我假设这个解决方案通常可以工作,但它只适用于普通类型的数组。
    猜你喜欢
    • 1970-01-01
    • 2016-07-12
    • 1970-01-01
    • 2018-09-04
    • 1970-01-01
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 2016-11-09
    相关资源
    最近更新 更多