多核处理器编程

时间:2010-03-18 06:20:59

标签: programming-languages hardware parallel-processing multicore processor

据我所知,处理器中的多核架构不会影响程序。实际的指令执行在较低层处理。

我的问题是,

鉴于您拥有多核环境,我是否可以使用任何编程实践来更有效地利用可用资源?我应该如何更改代码以在多核环境中获得更高的性能?

4 个答案:

答案 0 :(得分:15)

这是正确的。除非你使用并发,否则你的程序运行速度不会更快(除了核心处理更少的其他进程,因为某些进程正在另一个核上运行)。但是,如果使用并发性,则更多内核可以改善实际的并行性(内核更少,并发性是交错的,而使用更多内核,可以在线程之间获得真正的并行性)。

使程序高效并发并非易事。如果做得不好,让你的程序并发实际上可以让它变慢!例如,如果您花费大量时间生成线程(线程构造非常慢),并且在非常小的块大小上工作(因此线程构造的开销主导实际工作),或者您经常同步数据(这不仅强制操作串行运行,而且还有很高的开销),或者如果你经常在多个线程之间的同一缓存行中写入数据(这可能导致整个缓存行在一个线程上失效) (核心),那么你可以通过并发编程严重损害性能。

同样重要的是要注意,如果您有N个核心,那并不意味着您将获得N的加速。这是加速的理论限制。实际上,可能有两个内核,它的速度是原来的两倍,但有四个内核可能快三倍,然后有八个内核,速度快三倍半,等等。你的程序实际上有多好能够利用这些核心称为并行可扩展性。通信和同步开销通常会阻止线性加速,但在理想情况下,如果可以尽可能避免通信和同步,则可以接近线性。

如何在StackOverflow上编写高效的并行程序是不可能的。这实际上是至少一门(可能是几门)计算机科学课程的主题。我建议你报名参加这样的课程或买书。如果我知道一本好书,我会向你推荐一本书,但是我参加的并列算法课程没有课程的教科书。您可能还有兴趣使用串行实现编写一些程序,使用多线程(常规线程,线程池等)的并行实现,以及使用消息传递的并行实现(例如使用Hadoop,Apache Spark,Cloud Dataflows) ,异步RPC等),然后测量它们的性能,在并行实现的情况下改变核的数量。这是我的并行算法课程的大部分课程工作,可以非常有见地。您可能尝试并行化的一些计算包括使用蒙特卡罗方法计算Pi(这可以简单地并行化,假设您可以创建随机数生成器,其中在不同线程中生成的随机数是独立的),执行矩阵乘法,计算行的梯形式一个矩阵,将数字1 ...的平方相加为一些非常大的N,我相信你可以想到其他人。

答案 1 :(得分:4)

我不知道这是否是最好的起点,但我已经订阅了Intel Software Network前一段时间的文章供稿,并在那里找到了很多有趣的东西,以非常简单的方式呈现。您可以找到一些关于并行计算基本概念的基础文章,如thisHere您可以快速了解openMP,这是开始并行化应用程序最慢部分的一种可能方法,而无需更改其余部分。 (当然,如果这些部分呈现并行性。)同时检查Intel Guide for Developing Multithreaded Applications。或者只是去浏览the article section,文章不是太多,所以你可以快速找出最适合你的文章。他们还有一个论坛和一个名为Parallel Programming Talk的每周webcast

答案 2 :(得分:3)

是的,只需在不更改软件的情况下向系统添加更多内核就不会产生任何结果(操作系统除外,它可以在不同的内核上安排多个并发进程)。

要让您的操作系统使用多个内核,您需要执行以下两项操作之一:增加每个进程的线程数,或者增加同时运行的进程数(或两者兼而有之!)。

然而,有效利用核心是一种不同颜色的野兽。如果您花费太多时间在线程/进程之间同步共享数据访问,则当线程彼此等待时,您的并发级别将受到影响。这也假设您有一个可以相对容易地并行化的问题/计算,因为算法的并行版本通常比其顺序版本复杂得多。

也就是说,特别是对于工作单元彼此独立的CPU绑定计算,当您在问题上抛出更多线程时,您很可能会看到线性加速。当您添加串行段和同步块时,此加速将趋于减少。

I / O繁重的计算通常会在多线程环境中造成最坏的情况,因为对物理存储的访问(特别是如果它位于同一个控制器或相同的介质上)也是串行的,在这种情况下,线程变得更多在某种意义上它是有用的,它可以释放你的其他线程来继续进行用户交互或基于CPU的操作。

答案 3 :(得分:0)

您可以考虑使用专为并发编程设计的编程语言。 Erlang和Go浮现在脑海中。