【问题标题】:Using make_shared with shared_ptr<T>s only beneficial for T < 56 bytes?使用 make_shared 和 shared_ptr<T>s 只对 T < 56 字节有益?
【发布时间】:2014-07-09 12:51:08
【问题描述】:

据我了解,如果您使用std::make_shared,它会在创建引用计数对象的同时创建底层对象。

但是,如果 smart_ptr 指向的对象指针大于 56 字节,那么引用计数器最终不会位于不同的缓存行中(因为缓存行是 64 字节)?

【问题讨论】:

  • make_shared 的重点是内存分配很昂贵,所以我们应该做一次
  • 因为提出了一个体面的问题而投了反对票.....太棒了!所以我们只能问我们已经知道答案的问题吗? ;)
  • 差别不大,但确实存在。 Live Example.
  • 即使数据可能不在同一个缓存行中,但指向数据的指针和 refcount 在一起分配时更有可能在同一页中,从而减少了访问 shared_ptr 时的 TLB 缓存。不过,这些影响非常小。
  • 您不希望它们位于不同的缓存行上,以便增加/减少引用计数不会取消共享不变的对象吗?

标签: c++ c++11 memory-management shared-ptr make-shared


【解决方案1】:

注意: cache-line 在每个平台上的大小都不相同,指针的大小也不总是相同的。请注意根据问题中的数字做出假设。


为什么是std::make_shared

std::make_shared 存在有三个(主要)原因;

  • 意味着同时为 ref-counter 和被跟踪的对象分配内存(通常内存分配很昂贵);
  • 一种构造和初始化std::shared_ptr 的异常安全方法;
  • 代码简洁。

缓存行和std::make_shared 呢?

老实说,这超出了std::make_shared 的范围和目的。 C++ 标准不知道什么是“cache-line”,并且标准中描述的设计是这样编写的,它不针对任何特定平台。

即使由于 ref-counter 和对象无法放入同一个 cache-line 内而产生 *cache-misse*s,我们仍然有之前列出的所有好处,std::make_shared 仍然可以完成它打算解决的工作。

注意:可以说“在内存中保持引用计数器和对象靠近”只是一个甜蜜的小奖励。

【讨论】:

  • make_shared的另一点是能够封禁newdelete。这本身就有价值。
  • @nwp 肯定包含在“异常安全”;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-20
  • 1970-01-01
  • 1970-01-01
  • 2018-02-19
  • 1970-01-01
相关资源
最近更新 更多