大规模和硬件并发是21世纪的热门话题。 这样做有几个很好的理由,而其中一个则令人遗憾。
两个很好的理由:游戏中出色的GPU性能的结合,以及它们在AI深度学习中的意外使用,这是因为大量并行处理是在硬件级别上实现的。 可悲的原因是,自2006年以来,单处理器系统的速度一直违反物理定律。 当前的泄漏和热击穿问题严重限制了时钟频率的增加,而经典的电压降现在已成为量子噪声的严重问题。
为了吸引公众的注意力,处理器制造商正试图将越来越多的处理器内核推入每个芯片中,并吹捧理论上的整体性能。 在后台使用多线程的传送工作和推测执行方法也在迅速增长,因此程序员可见的单个处理器可以更快地处理指令。
不方便的事实是,我们许多不太吸引人的计算任务根本无法很好地
使用可见多线程。 造成这种情况的原因有很多,它们对程序员有不同的后果,并且存在很多混乱。 在本文中,我想澄清一些情况。
首先,您需要清楚地了解硬件并行性在哪里工作最好,以及为什么这样做。 让我们看一下图形,神经网络,信号处理和比特币挖掘的计算。 有一种模式:并行化算法最适合在以下设备上运行:(a)专为运行它们而设计的设备; (b)无能为力!
我们还看到,最成功的并行算法(排序,字符串匹配,快速傅立叶变换,矩阵运算,图像的逆量化等)的输入看起来非常相似。 通常,它们具有度量结构,并且隐含“近”和“远”数据之间的差异,这使我们可以将它们划分为多个部分,因为远方元素之间的联系不重要。
就上一篇关于语义局部性的文章而言,我们可以说并行方法主要适用于数据具有良好局部性的情况。 而且它们在仅支持“短距离”连接的设备上效果最佳,例如GPU心脏中的脉动矩阵。
另一方面,在通用计算机(冯·诺伊曼体系结构)上,编写一种软件可以有效地产生这样的部分来输入位置差的数据是非常困难的。
结果,我们可以制定一个简单的试探法:
使用并行计算的
机会与输入数据中不可还原的语义非局部性的程度成反比。并行计算的另一个局限性是,一些重要的算法根本无法并行化-即使在理论上也是如此。 当我在博客上首次讨论此主题时,我想到了“病态算法”一词,其中SICK代表“串行,本质地-应付,孩子!”。 重要的例子包括:Dijkstra的寻找最短路径的算法; 在有向图中检测循环(在求解器中使用3-SAT); 深度搜索 计算加密哈希链中的第n个成员; 网络流优化...,这不是完整列表。
输入数据的局部性在这里也很重要,尤其是在图形和树形结构的情况下。 加密散列链无法并行化,因为记录是按严格顺序计算的-这实际上是保护链不受伪造的重要规则。
锁定就在这里:SICK算法运行时您无法并行化任何东西。
我们还没有完成。 至少有两类障碍,而且很常见。
首先,没有必要的工具。 大多数语言不支持互斥和信号量。 这很方便,原语易于实现,但是这种情况会导致头部复杂性的可怕爆炸:几乎不可能理解四个以上互锁的规模。
如果幸运的话,您将获得一组更加宽松的原语,例如Go通道(又名Communicating Sequential Sequential Processes)或Rust拥有权/发送/同步系统。 但是实际上,我们不知道什么是冯·诺依曼体系结构上实现并行性的基元的“正确”语言。 也许甚至没有一组正确的基元。 也许有两个或三个不同的集合适合于不同的问题领域,但是它们作为一个单位和两个平方根是不可估量的。 迄今为止,在2018年还没有人真正知道。
最后但同样重要的限制是人脑。 即使采用具有良好数据局部性和有效工具的清晰算法,即使对算法的应用非常简单,并行编程也仍然
很困难 。 我们的大脑不能很好地建模纯顺序程序(尤其是并行程序)的最简单状态空间。
我们之所以知道这一点,是因为有大量的真实证据表明,调试并行代码非常困难。 这是由于竞争条件,死锁,自毁锁,隐匿的数据损坏(由于指令顺序略有不安全)而造成的。
我认为,
在缩放Dennard定律后,理解这些限制变得更加重要。 由于编程中存在所有这些瓶颈,因此多核系统的一部分将始终运行无法以100%的计算能力加载设备的软件。 如果您从另一侧看,我们目前的任务有多余的铁。 我们浪费了多少金钱和精力?
处理器制造商希望您高估具有更多内核的智能新芯片的功能优势。 他们还能如何筹集资金来支付庞大的生产成本,同时又保持盈利? 市场营销正在尽力而为,所以您永远都不会怀疑多线程这样的任务真正有益。
老实说,有这样的任务。 数据中心中每秒处理成千上万并发事务的服务器可能会很好地在核心之间分配负载。 智能手机或嵌入式系统也是如此-在这两种情况下,都在尽最大努力使成本和能耗最小化,从而防止了过剩功率的投入使用。
但是对于普通台式机和笔记本电脑用户呢? 含糊的疑问困扰着我。 这里的情况很难理解,因为生产率的真正提高来自其他因素,例如从HDD过渡到SSD。 如果您不进行全面的分析,则这些成就很容易被误认为是加速CPU的效果。
这是引起怀疑的理由:
- 台式机/笔记本电脑上的严重并行计算仅在GPU上发生。
- 处理器中的两个以上内核通常是无用的。 操作系统可以分发应用程序流,但是典型的软件无法使用并发性,并且大多数用户很少设法同时启动大量消耗大量CPU资源来完全加载其设备的大量不同应用程序。
- 因此,大多数四核系统在大多数情况下不做任何事情,只是产生热量。
在我的读者中,有许多人可能能够合理地评论这一假设。 看到他们说的话很有趣。
更新 G +的评论者指出了多核处理器的一个有趣的好处:它们可以非常快速地编译代码。 诸如C之类的语言的源代码具有很好的局部性:在这里,将分隔良好的单元(源文件)编译为目标文件,然后链接程序将其合并。