首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >性能与C++内存模型

性能与C++内存模型
EN

Stack Overflow用户
提问于 2014-01-21 15:00:36
回答 5查看 281关注 0票数 4

有了C++11新的共享内存并发特性,两个线程就有可能同时分配内存。此外,由于编译器事先不知道编译后的代码是否将由多个线程同时运行,所以它必须假设最坏的情况。因此,我的想法是,编译后的代码必须以某种方式同步访问堆。这将减缓不需要同步的单线程代码。

这不是与C++的格言“你只为你所用的东西付费”形成对比吗?开销如此之小,以至于被认为不重要吗?C++内存模型是否会降低代码的速度,而这些代码最终只能被单独使用?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2014-01-21 15:12:08

堆管理器确实需要同步,这是多线程代码可能存在的性能问题。如果有必要的话,应该由该项目来缓解这种情况。标准库也在做出反应,试图获得更好的多线程分配器。

编辑:我对第二段中的问题有一些思考。

即使是C++,也需要足够安全才能使用。"YDPFWYU“很不错,但是如果这意味着如果您想在多线程环境中使用代码,就必须在每个分配中包装一个互斥,那么您就有了一个大问题。实际上,这就像异常:即使不积极使用它们的代码也应该意识到它可能在存在的上下文中使用,而程序员和编译器都需要知道这一点。编译器需要创建异常支持代码/数据结构,而程序员则需要编写异常安全代码。多线程是一样的,更糟糕的是:您编写的任何代码都可能在多线程环境中使用,因此您需要编写线程安全的代码,编译器/环境需要注意线程(放弃一些非常不安全的优化,并有一个线程安全的分配器)。

就标准而言,这是C++中的要点,您甚至可以为不使用的东西付费。您的特定编译器可能会为您提供一个转义舱口(禁用异常,使用单线程运行时库),但这不再是真正的C++。

也就是说,即使(特别是)如果您有一个全局分配程序锁,单线程程序的开销也是最小的:锁只有在争用时才会很昂贵。与分配器操作的其余部分相比,无争用互斥锁/解锁并不是非常重要。

在争论中,故事是不同的,这就是自定义分配器可能出现的地方。

正如我上面简要提到的,C++中的另一个地方由于多线程的存在而稍微放慢了速度:禁止某些特定的优化。编译器不能在代码路径中发明读写(特别是写)到可能的共享变量(比如全局变量或发出指针的东西),这些代码路径通常不会有这些访问。这可能会减慢非常具体的代码片段,但总的来说,在程序中,您不太可能注意到这一点。

票数 3
EN

Stack Overflow用户

发布于 2014-01-21 15:17:02

您正在混合堆内存的分配和访问。

多线程堆分配确实是同步的,但在C库级别上是如此,至少在当前所有的OSes‘C库中都是如此。可能有一些特定用途的C库不这样做。例如,请参见用于MSVC的旧的单线程和多线程C运行库 (请注意新版本的MSVS如何废弃,甚至删除单线程变体)。我假设glibc有类似的机制,而且可能也是完全多线程的,所以总是同步的。我没有听到任何人抱怨多线程内存分配速度,所以如果您有一个具体的抱怨,我希望看到它正确地解释和用可复制的代码进行记录。

访问堆内存(即对newmalloc的调用返回后)不受任何机制的保护。C++11为您提供了mutex和其他同步的可能性,您作为用户,如果想要保护不受竞争条件的影响,就需要在代码中实现这些功能。如果你不这样做,就不会失去任何惩罚。

票数 3
EN

Stack Overflow用户

发布于 2014-01-22 11:32:50

编译器实际上没有被迫不进行优化。总是有可能成为一个非常糟糕的编译器和“标准”库。而现在,它只不过是劣质而已。尽管如此,它可能被宣传为“唯一的物权C++”。

“您编写的任何代码都可能在多线程环境中使用,因此您需要编写线程安全的代码,编译器/环境需要注意线程处理”--这是一个明显的愚蠢。

良好的实现总是可以提供一种正常的方法来优化单线程代码(和必要的库.),以及不使用异常的代码,并允许其他特性.

(例如,线程处理需要一些特定的函数来协调线程和创建线程,并且在链接时它们的使用是可见的,可能会影响工具链.或者在第一次调用线程创建函数时,它可能会影响内存分配方法(并且会产生其他效果),并且可能有其他好的方法,比如对编译器的特殊切换等等。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21261648

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档