我在网上读到,大多数现代的Unix系统默认情况下都带有线程安全的Malloc().我知道这仅仅意味着一个线程可以安全地调用Malloc(),而另一个线程本身已经在调用Malloc().

我正在使用p线程进行我的多线程.我有一个12核的CPU,每个核有2个线程.所以总共有24个线程.另外,我使用的是Malloc的GNU C库实现.

我的问题是如何在不锁定/等待/阻塞的情况下同时执行这些操作.我在回复中看到,当多个线程同时调用Malloc()时,它"使用内部锁定机制".

So here's my question exactly:

如果8个线程恰好同时调用Malloc(),是否会有8个并行发生的Malloc调用,并且它们不会相互干扰?

或者情况是这样的:当一个线程调用Malloc()时,用于该线程的Malloc调用的其他线程MUST WAIT完成BEFORE,它们可以继续它们自己的Malloc调用?

(我之所以问这个问题,是因为我刚刚对我的一个C程序进行了多线程处理,该程序确实大量使用了Malloc()和Free(),并且加速比与所使用的线程不是线性的,尽管在逻辑上它应该是线性的,因为没有线程依赖于任何全局事务,所以不应该发生争用(无论如何在软件中).我的场景很简单:每个线程调用一个大约需要315秒才能在一个线程上完成的函数(没有多线程),这会对我定义的函数进行数百万次其他调用.由于函数代码是只读的,假设每个线程使用自己的参数调用它,并且没有线程依赖于任何全局或共享的东西,那么并行运行这个顶级函数的X个线程的加速应该不会有问题.当我使用4个线程时,由于某种原因,时间从315秒增加到710秒,而当我使用8个线程时,时间增加到1400秒,even though each thread is doing exactly the same work that the one thread without multithreading was doing, and was taking 315 seconds to complete秒.那么,见鬼的是什么??)

推荐答案

如果8个线程恰好同时调用Malloc(),是否会有8个并行发生的Malloc调用,并且它们不会相互干扰?

这取决于malloc()的实施情况,以及其他因素.用于通用操作系统的现代C标准库通常迎合同时多处理.

例如,Glibc's malloc维护多个可供分配的内存区,以避免单个malloc()调用强制所有其他调用阻塞,直到其完成.它会自适应地管理这些内容,但默认情况下是allows up to eight times as many arenas as there are CPUs in the system.当然,这是按进程计算的.如果您在基于Glibc的系统上运行,那么您的8 malloc呼叫可能确实是同时进行的.没有任何干扰是一个非常高的门槛,但我认为可以肯定地说,通常会有最小的干扰.

在其他系统上,答案可能不同.特别值得一提的是,Windows的分配器总体上性能不佳,尽管我不知道它在多线程应用程序中的处理情况.


然而,如果您的线程执行的动态内存管理如此之多,以至于您认为这可能是性能问题的一个来源,那么可能就太多了.即使这不是增加线程数量的具体问题,mallocfree的速度也相对较慢,所以在性能很重要的地方应该尽量减少它们的使用.

C++相关问答推荐

数组元素的编号索引

当打印字符串时,为什么在c中没有使用常量限定符时我会收到警告?

如果dim指定数组中的数据量,使用dim-1会不会潜在地导致丢失一个元素?

进程已完成,退出代码为138 Clion

是什么让numpy.sum比优化的(自动矢量化的)C循环更快?

用C++实现余弦函数

在另一个函数中使用realloc和指针指向指针

Boyer Moore算法的简单版本中的未定义行为

当b是无符号字符时,int a=(b<;<;2)>;>;2;和int a=b&;0x3F;之间有什么区别?

链接到底是如何工作的,我在这里到底做错了什么

我在反转双向链表时遇到问题

C堆栈(使用动态数组)realloc内存泄漏问题

使用ld将目标文件链接到C标准库

如何使这个While循环在新行上结束

浮动目标文件,数据段

程序如何解释变量中的值

为什么我在我的代码中得到错误和退出代码-1073741819(0xC0000005),但如果我添加了一个不相关的打印语句,它仍然有效?

区分MySQL C界面中的文本和BLOB字段

段错误try 访问静态字符串,但仅有时取决于构建环境

无法在 C 中打开文本文件,我想从中读取文本作为数据并将其写入数组