你是如何利用Multicore的?

时间:2008-12-12 16:44:43

标签: concurrency scalability parallel-processing multicore

作为HPC来自企业网络开发世界的人,我总是很想知道开发人员回到“现实世界”中如何利用并行计算。现在all chips are going multicore更加相关,当芯片上有数千个内核而不是少数内核时它会更加相关。

我的问题是:

  1. 这对您的软件路线图有何影响?
  2. 我对有关多核如何影响不同软件域的真实故事特别感兴趣,因此请指明您在答案中所做的开发类型(例如服务器端,客户端应用程序,科学计算)等等)。
  3. 您正在使用现有代码来利用多核计算机,以及您面临的挑战是什么?您使用的是OpenMPErlangHaskellCUDATBBUPC还是其他什么?
  4. 随着并发级别的不断提高,您打算做什么?您将如何处理数百或数千个核心?
  5. 如果你的域不能轻易从并行计算中受益,那么解释原因也很有趣。
  6. 最后,我将此视为多核问题,但随意谈论其他类型的并行计算。如果您要移植部分应用以使用MapReduce,或者大型群集上的MPI是适合您的范例,那么请务必提及。

    更新:如果您回答#5,请提及您是否认为如果有更多内核(100,1000等)可以改变,那么您可以使用可用内存带宽(见每个核心的带宽越来越小)。您仍然可以将剩余的核心用于您的应用程序吗?

22 个答案:

答案 0 :(得分:38)

我的研究工作包括编译器和垃圾邮件过滤方面的工作。我也做了很多'个人生产力'的Unix东西。另外,我编写和使用软件来管理我教授的课程,包括评分,测试学生代码,跟踪成绩以及无数其他琐事。

  1. 多核影响我根本不会,除非作为编译器支持其他应用程序的研究问题。但是那些问题主要在于运行时系统,而不是编译器。
  2. Dave Wortman在1990年左右表示你可以并行化编译器以保持四个处理器忙碌。我认识的任何人都没有重复这个实验。 大多数编译器都足够快来运行单线程。并行运行顺序编译器在几个不同的源文件上比在编译器本身并行上容易得多。对于垃圾邮件过滤,学习是一个固有的顺序过程。即使是较旧的机器也可以每秒学习数百条消息,因此即使是大型语料库也可以在一分钟内学会。再次,培训足够快
  3. 我使用并行计算机的唯一重要方法是使用parallel make 。这是一个很好的福音,大型构建很容易并行化。 Make会自动完成所有工作。我记得的唯一另一件事就是使用并行性来计算长时间运行的学生代码,将其分配给一堆实验室机器,我可以很好地做到这一点,因为我每台机器只打破一个核心,所以只使用1 / 4个CPU资源。哦,我写了一个Lua脚本,在使用lame翻录MP3文件时将使用所有4个核心。为了做对,这个脚本需要做很多工作。
  4. 我将忽略数十,数百和数千个核心。我第一次被告知“并行机器即将到来;你必须做好准备”是1984年。那时确实如此,并行编程是高技能专家的领域。唯一改变的是,今天制造商正在迫使我们支付并行硬件,无论我们是否愿意。但是仅仅因为支付硬件并不意味着它可以自由使用。编程模型非常糟糕,并使线程/互斥模型工作,更不用说表现良好了,即使硬件是免费的,也是一项昂贵的工作。我希望大多数程序员忽略并行性并悄悄地继续他们的业务。当熟练的专家带来并行制作或精彩的电脑游戏时,我会默默地鼓掌并利用他们的努力。如果我想要自己的应用程序的性能,我将专注于减少内存分配并忽略并行性。
  5. 并行真的很难。 大多数域很难并行化。一个广泛可重复使用的例外,例如parallel make,是令人欢欣鼓舞的原因。
  6. 摘要(我从一位为一家领先的CPU制造商工作的主题发言人那里听到):业界支持多核,因为他们不能让机器运行得更快更热,他们不知道如何处理额外的晶体管。现在他们迫切希望找到一种方法来使多核盈利,因为如果他们没有利润,他们就无法建立下一代的生产线。肉汁火车结束了,我们实际上可能必须开始关注软件成本。

    许多认真对待并行性的人都忽视了这些玩具4核甚至32核的机器,转而使用128个或更多处理器的GPU。我的猜测是真正的行动将在那里。

答案 1 :(得分:18)

对于Web应用程序,它非常非常容易:忽略它。除非你有一些真正需要并行完成的代码,否则你可以简单地编写旧式的单线程代码并感到高兴。

在任何特定时刻,您通常需要处理的内容要多于拥有内核的请求。而且由于每个都是在自己的线程中处理(甚至是处理,取决于你的技术),这已经在并行工作了。

唯一需要注意的地方是访问某种需要同步的全局状态。将其保持在最低限度,以避免在其他(几乎)完全可扩展的世界中引入人为瓶颈。

所以对我来说,多核心基本上归结为这些项目:

  • 我的服务器拥有较少的“CPU”,而每个服务器都运行更多核心(对我来说没什么区别)
  • 相同数量的CPU可以吸收更多的并发用户
  • 如果似乎是性能瓶颈 CPU的结果是100%加载,那么这表明我在某处做了一些不好的同步。

答案 2 :(得分:9)

我从事医学影像和图像处理工作。

我们处理多个内核的方式与处理单个内​​核的方式大致相同 - 我们在编写的应用程序中已经有多个线程,以便拥有响应式UI。

但是,因为我们现在可以,我们正在强烈关注在CUDA或OpenMP中实现大多数图像处理操作。英特尔编译器为OpenMP提供了许多优秀的示例代码,并且只是比CUDA更成熟的产品,并提供了更大的安装基础,因此我们可能会采用这种方式。

如果可以的话,我们倾向于为昂贵(即超过一秒)的操作做的事情是将该操作分成另一个进程。这样,主UI仍然保持响应。如果我们不能,或者移动那么多内存太不方便或太慢,那么操作仍然在一个线程中,然后该操作本身就会产生多个线程。

我们的关键是确保我们不会遇到并发瓶颈。我们在.NET中开发,这意味着必须通过对UI的Invoke调用来完成UI更新,以便让主线程更新UI。

也许我很懒,但实际上,我不想花太多时间在并行化矩阵反转之类的东西时想出很多这样的东西。许多非常聪明的人花了很多时间像亚硝酸盐一样快速制作这些东西,我只是想把他们所做的事情称之为。像CUDA这样的东西有一个有趣的图像处理界面(当然,这就是它的定义),但对于那种即插即用的编程来说仍然太不成熟。如果我或其他开发人员获得了大量的业余时间,我们可能会尝试一下。因此,我们将使用OpenMP来加快处理速度(这绝对是未来几个月的开发路线图)。

答案 3 :(得分:9)

  1. 目前 - 说实话并不会影响那么多。我更多地处于“准备阶段”,了解使这成为可能的技术和语言功能。
  2. 我没有一个特定的域名,但是我遇到了像数学这样的域名(多核心必不可少),数据排序/搜索(多核心上的分治和征服)以及多台计算机要求(例如,要求备用站的处理能力 用于某事)。
  3. 这取决于我正在使用的语言。显然在C#中,我的手与尚未准备好的并行扩展实现相关联,这似乎可以提高性能,直到您开始将相同的算法与OpenMP进行比较(可能不是公平的比较)。所以在.NET上,使用forParallel.For重构等等,这将是一个轻松的过程。
    事情变得非常有趣的是,因为C ++,与.NET相比,您可以挤出OpenMP之类的性能是惊人的。事实上,OpenMP让我感到很惊讶,因为我没想到它会如此高效地工作。好吧,我猜它的开发人员有很多时间来改进它。我也喜欢它可以在开箱即用的Visual Studio中使用,不像你需要付费的TBB。
    至于MPI,我使用PureMPI.net进行小型家庭项目(我有一个局域网)愚弄一台机器无法完全采用的计算。我从来没有在商业上使用MPI,但我知道MKL有一些MPI优化的功能,对于需要它们的人来说可能会很有趣。
  4. 我打算做'轻浮计算',即使用额外的内核来预先计算可能需要或可能不需要的结果 - 当然RAM允许。我还打算深入研究大多数最终用户的机器现在无法处理的昂贵的算法和方法。
  5. 至于那些不受并行化影响的领域......好吧,总能找到一些东西。我强烈关注的一件事是在.NET中获得了不错的支持,但令人遗憾的是,我已经放弃了希望可以达到类似于C ++的速度。

答案 4 :(得分:6)

我正在开发ASP.NET Web应用程序。在我的代码中直接使用多核的可能性很小,但是IIS在加载时会产生多个工作线程/进程,因此可以很好地扩展多核/ CPU。

答案 5 :(得分:6)

到目前为止,仅仅使用make进行更有效的编译:

gmake -j

-j选项允许不依赖于彼此的任务并行运行。

答案 6 :(得分:5)

我们在使用F#的.NET 4中的任务并行性方面取得了很大成功。我们的客户迫切希望获得多核支持,因为他们不希望他们的n-1核心闲置!

答案 7 :(得分:4)

我正在进行图像处理。我们通过处理切片中的图像到不同的线程,尽可能利用多核。

答案 8 :(得分:3)

我在回答一个不同的问题时说了一些(希望这没关系!):有一个名为 Flow-Based Programming (FBP)的概念/方法已经存在了30多年,并且正在被使用处理大型加拿大银行的大部分批处理。它在Java和C#中具有基于线程的实现,尽管早期的实现是基于光纤的(C ++和大型机汇编程序)。利用多核问题的大多数方法都涉及尝试采用传统的单线程程序并确定哪些部分可以并行运行。 FBP采用了不同的方法:应用程序从一开始就根据多个异步运行的“黑盒”组件进行设计(考虑制造装配线)。由于组件之间的接口是数据流,因此FBP本质上与语言无关,因此支持混合语言应用程序和特定于域的语言。发现以这种方式编写的应用程序比传统的单线程应用程序更易于维护,并且即使在单核机器上也经常花费较少的时间。

答案 9 :(得分:2)

我的毕业工作是开发做裸机多核工作的概念。在嵌入式系统中进行相同的教学。

我也在使用F#工作,以提升我的高级多进程语言功能,以加快速度。

答案 10 :(得分:2)

我相信“ Cycles是工程师最好的朋友”。

我公司提供商业分析工具 并且转变非常 许多计算机语言的大型软件系统。 “大”意味着1000万到3000万行代码。 该工具是DMS Software Reengineering Toolkit (简称DMS)。

在如此庞大的系统上进行分析(甚至转换) 需要很长时间:我们的分数为C分析仪 在具有16 Gb RAM的x86-64上,代码需要90个CPU小时。 工程师希望得到更快的答案。

因此,我们在PARLANSE中实施了DMS, 我们自己设计的并行编程语言, 旨在利用小规模多核共享 记忆系统。

parlanse背后的主要观点是: a)让程序员暴露并行性, b)让编译器选择它可以实现的部分, c)将上下文切换保持在绝对最小值。 计算的静态偏序是 一个容易帮助实现所有3;说起来容易, 相对容易衡量成本, 编译器易于安排计算。 (用这个写并行快速排序是微不足道的。)

不幸的是,我们在1996年做到了这一点:-( 最近几年终于得到了证明; 我现在可以以低于1K的价格在Fry's获得8台核心机器 和24台核心机器的价格差不多 汽车(可能会迅速下降)。

好消息是DMS现在相当成熟, 并且有许多关键的内部机制 在DMS中,尤其是利用了这一点 整类分析仪称之为“属性语法”, 我们使用特定于域的语言编写 这不是parlanse。 DMS编译这些 atrribute语法到PARLANSE,然后他们 并行执行。我们的C ++前端 end使用属性语法,大约是100K SLOC;它被编译成并行的800K SLOC 实际可靠运行的parlanse代码。

现在(2009年6月),我们非常忙于使DMS变得有用,并且 并不总是有足够的时间来利用并行性 好。因此90小时点 - 分析。 我们正在努力将其并行化,并且 有合理的希望加速10-20倍。

我们相信从长远来看,利用 SMP井将使工作站更加强大 友好的工程师提出难题。 他们也应该这样做。

答案 11 :(得分:2)

We创建VivaMP代码分析器,以便在并行的OpenMP程序中检测错误。

VivaMP是一个类似于lint的静态C / C ++代码分析器,用于指示基于OpenMP技术的并行程序中的错误。 VivaMP静态分析器大大增加了现有编译器的能力,诊断出任何有错误的并行代码,或者是这类错误的最终来源。该分析仪已集成到VisualStudio2005 / 2008开发环境中。

VivaMP – a tool for OpenMP

32 OpenMP Traps For C++ Developers

答案 12 :(得分:1)

我在Mac上使用和编程。 Grand Central Dispatch获胜。对Snow Leopard的Ars Technica评论有很多关于多核编程的有趣内容,以及人们(或者至少是Apple)正在使用它的地方。

答案 13 :(得分:1)

我决定在DEFLATE算法的实现中利用多个核心。 MArc Adler使用PIGZ(并行gzip)在C代码中做了类似的事情。我已经在DotNetZip v1.9中的托管代码库中提供了哲学等价物。这不是PIGZ的一个端口,而是一个类似的想法,是独立实现的。

DEFLATE背后的想法是扫描一个数据块,寻找重复的序列,构建一个“字典”,将一个简短的“代码”映射到每个重复序列,然后发出一个字节流,其中每个实例之一重复的序列被字典中的“代码”替换。

由于构建字典是CPU密集型的,因此DEFLATE是并行化的理想选择。我采用了Map + Reduce类型的方法,将传入的未压缩bytestreeam划分为一组较小的块(map),每个64k,然后单独压缩它们。然后我将得到的块连接在一起(减少)。每个64k块在其自己的线程上独立压缩,而不考虑其他块。

在双核机器上,这种方法在传统串行方法的大约54%的时间内压缩。在服务器级机器上,有更多可用内核,它可以提供更好的结果;没有服务器机器,我没有亲自测试,但人们告诉我它很快。


与多个线程的管理相关联的运行时(cpu)开销,与每个thead的缓冲区相关联的运行时内存开销,以及与连接块相关联的数据开销。因此,这种方法仅适用于较大的字节流。在我的测试中,超过512k,它可以获得回报。在此之下,最好使用串行方法。


DotNetZip作为库提供。我的目标是让所有这一切都透明化。因此,当缓冲区高于512kb时,库会自动使用额外的线程。应用程序无需执行任何操作,以便使用线程。它只是工作,当使用线程时,它神奇地更快。我认为这是一种合理的方法,可以让大多数libbraries被应用程序使用。


计算机能够智能地自动和动态地利用可并行算法上的资源会很好,但现在的情况是应用程序设计者必须明确地编写并行化代码。


答案 14 :(得分:1)

学习函数式编程语言可能会使用多个核心......代价高昂。

我认为使用额外的核心并不是很难。 Web应用程序不需要特别小心,因为Web服务器并行运行查询,因此存在一些不足之处。问题是长期运行的algorythms(长期是你所谓的长期)。这些需要在不相互依赖的较小域上拆分,或者同步依赖关系。很多algs可以做到这一点,但有时需要非常不同的实现(成本再次)。

所以,在你使用命令式编程语言之前,没有银弹,对不起。要么你需要熟练的程序员(代价高昂),要么你需要转向其他编程语言(代价高昂)。或者你可以简单地运气(网络)。

答案 15 :(得分:1)

我们的域逻辑主要基于工作流引擎,每个工作流实例都运行在ThreadPool上。

这对我们来说已经足够了。

答案 16 :(得分:1)

我现在可以使用虚拟PC或VMWare的虚拟化设置将我的主操作系统与我喜欢的开发/安装分开。

双核意味着一个CPU运行我的主机操作系统,另一个运行我的开发操作系统,具有相当的性能水平。

答案 17 :(得分:0)

  1. 这对您的软件路线图有何影响?
    它没有。我们(与几乎所有其他)业务相关的应用程序在单核上运行良好。只要添加更多内核并不会显着降低单线程应用程序的性能,我们很高兴

  2. ...真实故事......
    与其他人一样,并行构建是我们获得的主要好处。 Visual Studio 2008 C#编译器似乎并没有使用多个核心,这真的很糟糕

  3. 您正在使用现有代码来利用多核计算机
    如果我们有一个可以并行化的长期运行算法,我们可能会考虑使用.NET并行扩展,但实际发生的可能性很小。最可能的答案是,一些开发人员会为了感兴趣而玩它,但不是很多其他

  4. 您将如何处理数百或数千个核心?
    头 - >砂。

  5. 如果您的域名不易受益于并行计算,那么解释原因也很有趣。
    客户端应用程序主要是推送数据,服务器应用程序主要依靠SQL服务器来进行繁重的工作

答案 18 :(得分:0)

我使用.Net Threads在C#中工作。 您可以将面向对象的封装与线程管理相结合。

我读过Peter的一些帖子,谈论Packt Publishing的新书,我在Packt Publishing网页上找到了以下文章:

http://www.packtpub.com/article/simplifying-parallelism-complexity-c-sharp

我已经阅读了Joe Duffy的书中的Windows并发编程。现在,我正在等待“C#2008和2005线程编程”,Hillar的书 - http://www.amazon.com/2008-2005-Threaded-Programming-Beginners/dp/1847197108/ref=pd_rhf_p_t_2

我同意Szundi“没有银弹”!

答案 19 :(得分:0)

你说“对于Web应用程序来说,非常非常容易:忽略它。除非你有一些真正需要并行完成的代码,否则你只需编写旧式的单线程代码就可以了。” / p>

我正在使用Web应用程序,我确实需要充分利用并行性。 我理解你的观点。但是,我们必须为多核革命做好准备。忽略它与忽略90年代的GUI革命是一样的。

我们还没有为DOS开发?我们必须解决多核问题,否则我们将在很多年内死亡。

答案 20 :(得分:0)

我正在利用C,PThreads以及使用PREEMPT_RT补丁集的调度程序在Linux上的OpenVPX平台上使用通信顺序进程的家庭酿造实现多核。它在多个操作系统实例中的CPU利用率几乎达到100%,而且OpenVPX机箱中的处理器卡之间没有CPU时间用于数据交换,而且延迟也非常低。还使用sFPDP将多个OpenVPX机箱连接到一台机器中。我没有使用Xeon的内部DMA来减轻CPU内存压力(DMA仍以CPU内核为代价使用内存带宽)。相反,我们将数据留在原地并以CSP方式传递它的所有权(因此与.NET的任务并行数据流库的理念不同)。

1)软件路线图 - 我们有压力要求最大限度地利用房地产和可用电力。充分利用最新的硬件是必不可少的

2)软件领域 - 有效的科学计算

3)我们对现有代码做了什么?不断地将它分开并在线程之间重新分配它的一部分,以便在不破坏实时要求的情况下尽可能地最大化每个核心。新硬件意味着相当多的重新思考(更快的内核可以在给定的时间内完成更多,不希望它们被利用不足)。没有它听起来那么糟糕 - 核心例程非常模块化,因此很容易组装成线程大小的块。虽然我们计划从Linux中控制线程亲和性,但我们还没有设法通过这样做来提取显着的额外性能。 Linux非常擅长将数据和代码放在同一个地方。

4)实际上已经存在 - 总计机器已经增加了数千个核心

5)并行计算至关重要 - 它是一个MISD系统。

如果这听起来像很多工作,那就是。一些工作需要全力以赴制造绝对最多的可用硬件并避开几乎所有高级别的东西。我们发现总机器性能是CPU内存带宽的函数,而不是CPU核心速度,L1 / L2 / L3高速缓存大小。

答案 21 :(得分:0)

我认为这种趋势将首先说服一些开发人员,然后他们中的大多数人会发现并行化是一项非常复杂的任务。 我希望有一些设计模式可以解决这种复杂性。不是低级别的,而是建筑模式,这将很难做错事。

例如,我希望消息传递模式能够普及,因为它本身是异步的,但你不会考虑死锁或互斥或其他什么。

豫ICP备18024241号-1