性能与C 内存模型

Performance vs. C++ memory model

本文关键字:模型 内存 性能      更新时间:2023-10-16

具有C 11的新共享内存并发功能,两个线程可能可以同时分配内存。此外,由于编译器不知道编译的代码是否会在最坏的情况下由多个线程运行。因此,我的概念是,编译的代码必须以某种方式同步到堆的旅行。然后,这将减慢不需要同步的单线代码。

这与"您只为使用的费用付费"的C 格言形成鲜明对比?开销是否如此小,以至于不重要?C 内存模型减慢代码的其他区域是否最终仅单线使用?

堆管理员确实需要同步,并且对于多线程代码来说,这可能是可能的性能问题。在必要时可以减轻该计划。标准库也反应,试图获得更好的多线程分配器。

编辑:关于第二段中问题的一些想法。

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

就标准而言,即使您不使用的价格也可以支付的点。您的特定编译器可能会为您提供一个逃生舱口(禁用例外,使用单线程运行时库),但这不再是真正的C 。

也就是说,即使(尤其是)您有一个全球分配器锁,单线程程序的开销很小:锁在争夺时才昂贵。与其余的分配器操作相比

在争论中,故事不同,这是自定义分配的地方。

正如我在上面简短提到的那样,仅存在多线程:对某些特定优化的禁令,C 中的另一个位置会非常稍微放慢速度。编译器无法在代码路径中发明和写入(尤其是写入)可能共享的变量(例如全球变量或您分发出的指针),而这些变量通常不会访问这些访问。这可能会减慢非常具体的代码片段,但是总体而言,您不太可能注意到。

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

多线程堆的分配确实是同步的,但是在C库级别,至少在所有现代(CON)当前OSS的C库中。可能有特定的用途C库不执行此操作。例如,请参见MSVC的旧单线和多线Readed C运行时库(请注意MSVS的新版本如何贬低,甚至删除单线读变体)。我认为GLIBC具有相似的机制,并且可能仅是多线程,因此总是同步。我没有听说有人抱怨多线程的内存分配速度,因此,如果您有具体的投诉,我想看到它正确解释并记录了可重复的代码。

访问堆内存(即,在返回newmalloc的呼叫之后)不受任何机制的保护。C 11为您提供mutex和其他同步可能性,作为用户,如果您想保护竞赛条件,则需要在代码中实现。如果不这样做,就不会丢失变形。

编译器确实没有被迫没有优化。总是有可能制作一个非常糟糕的编译器和"标准"库。如今,这只是质量不好的。尽管它可能被广告为"唯一真正的右C "。

"您编写的任何代码都可以在多线程环境中使用,因此您需要编写线程安全代码,并且编译器/环境需要意识到线程" - 这是一个明显的愚蠢。<<<<<<<<<<<<<<

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

(例如,线程需要某些某些功能来坐标线程并创建线程,并且在链接时间可见,可能会影响工具链...或者首先致电线程创建功能,它可能会影响该功能内存分配方法(并且具有其他效果),并且可能还有其他好方法,例如编译器的特殊开关等...)

不是真的。物理内存和支持商店都是现代操作系统上的系统资源。因此,它们的分配和访问它们必须正确同步。

线程共享虚拟内存的情况只是调度实体可以共享虚拟内存的许多其他方式的特殊情况。考虑记忆映射同一库或数据文件的两个过程。

唯一带有线程的额外开销是对虚拟内存映射的修改,因为线程共享虚拟内存映射。大部分同步开销是不可避免的。例如,如果您要解开某些内容,则通常必须将某些资源返回到系统级池,这无论如何都需要同步。

在许多平台上,需要一些特定平台的特定功能,以使其他线程同时知道它们的虚拟内存观点已经改变。但是,如果没有其他线程,这无论如何都会消失,因为没有任何通知。

即使某些功能不使用,某些功能也具有成本,这只是一个现实。即使您从不交换,交换逻辑的存在和内核中的检查也有一些成本。工程师是现实主义者,必须平衡成本和收益。

物理内存和备份商店都是现代操作系统上的系统资源。因此,它们的分配和访问它们必须正确同步。

线程共享虚拟内存的情况只是调度实体可以共享虚拟内存的许多其他方式的特殊情况。

很快它是操作系统的功能,就无需在应用程序程序中的C/C 分配功能中使用其他代码(当然,多线程需要在标准LIB中进行特殊的附加同步。打电话"开始时查看问题)。

真正的麻烦可能是系统中的同一库(标准C/C 库以及其他库)的多种类型(单和多线程)...但是...