【发布时间】:2015-05-02 22:34:24
【问题描述】:
在他的演讲"Efficiency with algorithms, Performance with data structures" 中,Chandler Carruth 谈到了在 C++ 中需要更好的分配器模型。当前的分配器模型侵入了类型系统,因此几乎不可能在许多项目中工作。另一方面,Bloomberg allocator model 没有侵入类型系统,而是基于虚函数调用,这使得编译器无法“看到”分配并对其进行优化。在他的演讲中,他谈到了编译器对内存分配进行重复数据删除 (1:06:47)。
我花了一些时间找到一些内存分配优化的例子,但我发现了这个在 clang 下编译的代码示例,优化了所有的内存分配,只返回 1000000 而不分配任何东西。
template<typename T>
T* create() { return new T(); }
int main() {
auto result = 0;
for (auto i = 0; i < 1000000; ++i) {
result += (create<int>() != nullptr);
}
return result;
}
下面的论文http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3664.html 还说分配可以在编译器中融合,并且似乎表明一些编译器已经做了这种事情。
由于我对有效内存分配的策略非常感兴趣,我真的很想了解为什么 Chandler Carruth 在 Bloomberg 模型中反对虚拟调用。上面的例子清楚地表明,当它可以看到分配时,clang 会优化东西。
- 我想要一个“现实生活中的代码”,这种优化很有用,并且可以由任何当前的编译器完成
- 您有任何代码示例,其中不同的分配被当前编译器融合了吗?
- Chandler Carruth 在 1:06:47 的演讲中说编译器可以“删除”你的分配,你明白他的意思吗?
【问题讨论】:
-
create函数是具有运行时副作用的函数,编译器不可能在编译时知道这些运行时副作用的结果。它 can 所做的是看到分配的内存并没有真正在任何地方使用,这可能是它可能优化分配的原因,但我认为这是错误的,因为编译器无法在编译时预测结果。 -
@Joachim:这个例子已经在这里讨论过stackoverflow.com/questions/25668420/…。根据我帖子中提到的n3664,该标准是否允许尚不清楚。但似乎很多编译器已经这样做了。
标签: c++ memory memory-management optimization allocation