在多核机器上扩展多线程应用程序

Posted

技术标签:

【中文标题】在多核机器上扩展多线程应用程序【英文标题】:Scaling multithreaded applications on multicored machines 【发布时间】:2010-09-05 15:06:15 【问题描述】:

如果我们需要更高的性能,我正在处理一个项目。随着时间的推移,我们不断改进设计以实现更多并行工作(线程和分布式)。然后最新的步骤是将其中的一部分移到具有 16 个内核的新机器上。我发现我们需要重新考虑如何在共享内存模型中扩展至那么多内核。例如,标准的内存分配器就不够好。

人们会推荐哪些资源?

到目前为止,我发现 Sutter 的专栏 Dr. Dobbs 是一个好的开始。 我刚刚拿到了 The Art of Multiprocessor Programming 和 The O'Reilly 关于英特尔线程构建模块的书

【问题讨论】:

【参考方案1】:

另外几本书会有所帮助:

Synchronization Algorithms and Concurrent Programming Patterns for Parallel Programming Communicating Sequential Processes C. A. R. Hoare (该链接上的经典免费 PDF)

另外,考虑减少对并发进程之间共享状态的依赖。如果您可以避免这种情况,您的扩展会更好,因为您将能够分出独立的工作单元,而无需在它们之间进行尽可能多的同步。

即使您需要共享某些状态,请查看是否可以将共享状态与实际处理分开。这将使您能够并行执行尽可能多的处理,独立于将已完成的工作单元集成回共享状态。显然,如果您在工作单元之间存在依赖关系,这将不起作用,但值得研究一下,而不是仅仅假设状态总是会被共享。

【讨论】:

【参考方案2】:

您可能想查看Google's Performance Tools。他们发布了用于多线程应用程序的 malloc 版本。它还包括一组不错的分析工具。

【讨论】:

【参考方案3】:

Jeffrey Richter 非常喜欢线程化。他的书中有几章是关于线程的,请查看他的博客:

http://www.wintellect.com/cs/blogs/jeffreyr/default.aspx.

【讨论】:

【参考方案4】:

正如 monty python 所说的“现在做一些完全不同的事情”——您可以尝试一种不使用线程,而是使用进程和消息传递(无共享状态)的语言/环境。最成熟的其中之一是 erlang(以及这本出色而有趣的书:http://www.pragprog.com/titles/jaerlang/programming-erlang)。可能与您的情况不完全相关,但您仍然可以学到很多可以应用于其他工具的想法。

对于其他环境:

.Net 有 F#(学习函数式编程)。 JVM 有 Scala(它有演员,很像 Erlang,是功能性混合语言)。还有来自 Doug Lea for Java 的“fork join”框架,它为您做了很多艰苦的工作。

【讨论】:

【参考方案5】:

FreeBSD 中的分配器最近获得了 FreeBSD 7 的更新。新的称为 jemaloc,显然对于多线程而言更具可扩展性。

您没有提及您使用的是哪个平台,因此您可能可以使用此分配器。 (我相信Firefox 3 uses jemalloc,即使在 Windows 上也是如此。所以端口必须存在于某处。)

【讨论】:

【参考方案6】:

如果您正在分配大量内存,请查看Hoard。

滚动您自己的Lock Free List。一个很好的资源在这里 - 它在 C# 中,但想法是可移植的。一旦您习惯了它们的工作方式,您就会开始看到其他可以使用它们的地方,而不仅仅是在列表中。

【讨论】:

【参考方案7】:

我将不得不在某个时候检查 Hoard、Google Perftools 和 jemalloc。目前我们使用的是 Intel Threading Building Blocks 的scalable_malloc,它的性能足够好。

无论好坏,我们在 Windows 上使用 C++,尽管我们的大部分代码都可以使用 gcc 编译。除非有令人信服的理由迁移到 redhat(我们使用的主要 linux 发行版),否则我怀疑迁移是否值得头痛/政治麻烦。

我很想使用 Erlang,但现在有很多方法可以重做。如果我们考虑在电信环境中围绕 Erlang 开发的需求,它们与我们的世界(电子交易)非常相似。阿姆斯特朗的书在我的书架上 :)

在从 4 核扩展到 16 核的测试中,我学会了理解代码并行部分中任何锁定/争用的成本。幸运的是,我们有很大一部分可以随数据扩展,但由于额外的锁和内存分配器,即使这样一开始也不起作用。

【讨论】:

【参考方案8】:

我维护一个可能会持续感兴趣的并发链接博客:

http://concurrency.tumblr.com

【讨论】:

以上是关于在多核机器上扩展多线程应用程序的主要内容,如果未能解决你的问题,请参考以下文章

在多线程应用程序表单上使用while循环锁定c#阻塞单核机器上的所有线程

linux单进程如何实现多核cpu多线程分配?

数据库选型:多核还是多线程?

Node.js 多人游戏多线程和多核

多核CPU上python多线程并行的一个假象

多核CPU上python多线程并行的一个假象