如何优化双处理器,四处理器和更高的多处理器



朋友们,我已经编写高速软件超过20年了,并且几乎知道书中的每一个技巧,从微型工作台制作协作,分析,用户模式多任务,尾递归,你可以在Linux, Windows等上为非常高性能的东西命名。

问题是,当多线程的CPU密集型工作暴露给多核处理器时会发生什么,我发现自己很困惑。

在微基准测试中,线程之间(在不同的内核上)共享数据的各种方式的性能结果似乎不符合逻辑。

很明显,内核之间存在一些"隐藏的交互",这从我自己的编程代码中并不明显。我听说L1缓存和其他问题,但这些对我来说是不透明的。

问题是:我在哪里可以学到这些东西?我正在寻找一本关于多核处理器如何工作的深入的书,如何编程以利用它们的内存缓存或其他硬件架构,而不是被它们惩罚。

有什么建议或很棒的网站或书籍吗?在谷歌上搜索了很多次之后,我一无所获。

真诚,

这本书教会了我很多关于这类问题的知识,为什么原始CPU能力不是唯一需要注意的事情。我几年前在研究生院就用过它,但我认为所有的原则仍然适用:

http://www.amazon.com/Computer-Architecture-Quantitative-Approach-4th/dp/0123704901

基本上,多进程配置中的一个主要问题是同步对主存的访问,如果你做得不好,它可能会成为性能的真正瓶颈。这是相当复杂的缓存,必须保持同步。

我自己的问题,答案,在stackoverflow的姐妹网站:https://softwareengineering.stackexchange.com/questions/126986/where-can-i-find-an-overview-of-known-multithreading-design-patterns/126993#126993

我将复制答案以避免需要点击:

引用鲍里斯:

用microsoft.net并行编程:设计模式多核架构的分解与协调https://rads.stackoverflow.com/amzn/click/0735651590

这是一本我衷心推荐的书。

:

去年新出版的。意味着你的阅读没有过时实践。

短——大约200多页,信息密集。这些要读的东西太多了,要读1000多页的时间太少了书。

易于阅读-不仅写得很好,而且它

教学目的-每章给出练习。我知道它是这样做总是有益的,但很少这样做。这本书给出了引人注目和有趣的任务。令人惊讶的是,我做了大部分喜欢做这些事。

另外,如果你想了解更多的底层细节,这是我找到的最好的资源:"多处理器编程的艺术";它是使用java作为代码示例编写的,这与我的c#背景很好地配合。

PS:我有大约5年的"硬核"。并行编程经验,(学习使用c#)所以希望你能相信我,当我说"多处理器编程的艺术"的时候。岩石

  • 我对"你关心多核吗"的回答
  • Herb Sutter's articles
  • 并行编程系列视频

导致并行代码意外不良结果的一个具体原因是错误共享,如果您不知道下面发生了什么(我不知道),您将看不到这种情况的发生。这里有两篇文章讨论。net的原因和补救方法:

http://msdn.microsoft.com/en-us/magazine/cc872851.aspx

http://www.codeproject.com/KB/threads/FalseSharing.aspx

Rgds GJ

多线程有不同的方面需要不同的方法。

例如,在web服务器上,线程池的使用被广泛使用,因为它被认为"有利于"性能。这样的池可能包含数百个等待投入工作的线程。使用这么多线程将导致调度器超时工作,这对性能有害,但在Linux系统上无法避免。对于Windows,选择的方法是IOCP机制,它推荐的线程数量不大于安装的内核数量。它使应用程序成为(I/O完成)事件驱动的,这意味着在轮询上不会浪费任何周期。所涉及的少数线程将调度器的工作减少到最低限度。

如果对象要实现可扩展的功能(更多的内核<=>更高的性能),那么主要问题将是内存总线饱和。由于代码读取、数据读取和数据写入,会出现饱和。不正确实现的代码在使用两个线程时比使用一个线程时运行得慢。解决这个问题的唯一方法是通过主动地:

来减少内存总线工作。
  • 将代码裁剪到最小的内存占用(=适合代码缓存),并且不调用其他函数或到处跳跃。
  • 将内存读取和写入调整到最小大小。
  • 通知即将读取的RAM预取机制。
  • 调整工作,使在内核自己的缓存内执行的工作的比例(L1 &L2)与它们之外的工作(L3 &RAM)。

换句话说:将适用的代码和数据块装入尽可能少的缓存行(每条64字节),因为最终这将决定可伸缩性。如果缓存/内存系统能够每秒进行x次缓存行操作,那么如果代码的要求是每单位工作5次缓存行(=> x/5),而不是11次(x/11)或52次(x/52),那么它将运行得更快。

实现这一点并不容易,因为它每次都需要一个或多或少唯一的解决方案。有些编译器在指令排序方面做得很好,可以利用宿主处理器的流水线。这并不一定意味着它将是一个很好的多核排序。

可伸缩代码的有效实现不一定是漂亮的。推荐的编码技术和风格最终可能会阻碍代码的执行。

我的建议是通过用一种低级语言(如C)编写一个简单的多线程应用程序来测试它是如何工作的,该应用程序可以调整为在单线程或多线程模式下运行,然后分析不同模式下的代码。您需要在指令级别上分析代码。然后尝试使用不同的(C)代码结构、数据组织等。你可能不得不跳出框框,重新思考算法,使其对缓存更友好。

第一次将需要大量的工作。您将不会了解到什么适用于所有多线程解决方案,但您可能会了解到在分析分析代码时不应该做什么以及应该寻找什么指示。

我找到了这个链接,它专门解释了cpu上的多核缓存处理影响了我的多线程程序。

http://www.multicoreinfo.com/research/intel/mem-issues.pdf

站点multicoreinfo.com总的来说有很多优点关于多核编程的信息和参考。

最新更新