我在某处(忘记了那本书)读到算法独立于计算机体系结构。甚至有人说算法本身就是计算(机器?)?
另一方面,有关并行编程的书籍中有关于并行算法的章节。似乎并行算法依赖于并行体系结构?
我想我想念一些大照片吗?谢谢。
我在某处(忘记了那本书)读到算法独立于计算机体系结构。甚至有人说算法本身就是计算(机器?)?
另一方面,有关并行编程的书籍中有关于并行算法的章节。似乎并行算法依赖于并行体系结构?
我想我想念一些大照片吗?谢谢。
Answers:
算法是解决特定问题所采取的一系列步骤。如果可以的话,解决问题的方法。当然,“程序”执行相同的操作;我们使用“算法”来建议独立于特定机器设计,编程语言等的“通用”或“通用”配方。
算法本来应该是通用的,但是它们仍然可以取决于存在的某些功能。例如,“并发算法”可能取决于您是否具有某种机制,使不同程序可以同时运行。“分布式算法”可能取决于您在一个协作组中拥有多个系统,以及它们之间的网络或其他通信方案。同样,“并行算法”通常是设计为在具有多个处理单元时运行的那些算法-可能有许多处理单元,以及具有大量处理单元时常见的通信工具。即使只有一台计算机或一个CPU,您也可能能够运行“并行算法”,但是对于交通工程师而言,这并不是很有趣。
算法独立于计算机体系结构。这是因为算法定义了一系列解决问题的过程。无论采用哪种架构,排序算法都将始终进行排序。它不会突然在某些架构上渲染3D工程图。
如果您考虑一下,这实际上是直观的。当针对任何架构进行编译时,谷歌浏览器(仅是算法的集合)就是一种网络浏览器。在某些架构上,它不会突然成为设备驱动程序。
但是算法运行的速度取决于体系结构。根据架构的不同,某些算法的工作速度比其他算法快。
如果您考虑一下,这实际上也是直观的。给定一种算法,硬件设计人员总是有可能设计一种专门加速该算法的体系结构。这就是为什么会有3D加速图形卡和比特币矿工加速器之类的原因之一。
当人们谈论并行算法时,他们所谈论的是可以在并行体系结构上更快地工作的一系列算法。有很多并行架构无法改进的算法。因此,针对并行解决问题的新算法识别是一个活跃的研究领域。
但是那些算法仍然做同样的事情。架构不会改变他们的工作。
算法不依赖于计算机体系结构,但是运行任何特定算法的效率确实依赖于体系结构。任何Turing Complete机器都可以模仿任何其他Turing Complete机器,尽管某些机器在一件事上会比其他机器更好。
并发算法的意思是算法可以很好地发挥作用或可以利用机器中的并发性,这可能是因为它需要较少的锁定,而这不是为并发机器专门设计的算法所需要的,或者是因为该算法有效利用分而治之,充分利用了机器的全部力量。在非并发机器中运行算法仍然是可能的,但是效率可能不高,或者可能需要额外的锁定才能正确执行。
还有一些算法旨在利用特定体系结构的怪癖,例如优化缓存的缓存友好算法。这些算法在未缓存算法假定方式的计算机中效率可能较低。
是的,没有。这取决于您要满足的约束以及运行算法所需的前提条件。
理想情况下,算法是抽象的配方,它逐步定义了如何做某事。像这样定义算法是为了达到可重现性和后来实现自动化的目的。算法起源于lambda-calcul,因此您可以轻松了解为什么采用这种方法。这种定义是通常的定义,但是现代算法可以是非顺序的(不是逐步的(例如并发算法),也可以是逻辑的(例如使用统一的算法)),非线性(随机算法)或只是很奇怪(量子)算法),但我会通过。
因此,理想情况下,算法应尽可能抽象,而无需考虑任何硬件。
但是,与任何系统一样,您必须定义一些公理,不仅要获得一个连贯的系统,还要赢得时间。例如,大多数算法至少(至少是隐式地)假定它们是在Von-Neumann机器上定义的。如果不是这种情况,他们将需要明确定义要在其上运行的系统的每个部分(因为这是复制配方所必需的,这是一种先决条件)。而且,算法通常依赖于诸如write()之类的通用命令,而没有完全定义它们。
算法没有从硬件体系结构中抽象出来的另一个原因是当您需要满足一些约束条件时。
假设您正在嵌入式系统上工作,那么您可能无法依赖工作站上拥有的相同数量的资源。限制最大的资源之一可能是内存。但是,大多数算法都倾向于优化时间复杂度(在CPU上的执行速度),而不是内存复杂度(处理数据所需的内存量)。对于这些系统,已经设计了内存优化算法,其中非内存优化算法只会失败或运行得慢得多。实际上,嵌入式系统并不是内存效率高的算法的唯一目标:例如,有些缓存忽略型算法可以对其处理进行调整,以有效地使用CPU缓存。另一个示例:为大数据量身定制了一些机器学习算法增量学习或核心计算来处理大量数据,这些数据远大于任何计算机等上可用的内存。
还有一些算法不能优化计算机的特定部分,而是可以优化取决于硬件体系结构的标准。例如,需要精度的数值数据存储在float或double里面,由于硬件限制,它们自然受到限制。问题在于复杂的计算可能会导致舍入,并且对舍入后的数字进行的计算越多,则漂移会越多。这称为灾难性干扰。某些应用程序甚至在以最坏的复杂性为代价的情况下也需要严格的精度。对于此类应用,提出了优化计算以减少或消除灾难性干扰的算法。
因此,设计算法也可以在抽象和约束之间进行权衡。
最后,我们可以说算法既是目标的抽象,也是前提条件(架构)的抽象。您的算法目标越具体,目标对硬件体系结构的依赖就越多。
一些您可能感兴趣的相关关键字:
通常,您不应将算法与数学或计算算法混淆。如果您指的是计算算法,是的,它们与计算机体系结构无关。
维基百科中算法的定义:
在数学和计算机科学中,算法是要执行的独立的逐步操作集。存在执行计算,数据处理和自动推理的算法。
此定义用于引用一些封闭的计算或数据处理任务。换句话说,可以抽象地在Turing Machine上运行的计算。但是,最近在数学中有一个名为“ 交互式计算”的概念,涉及在计算过程中与外部世界进行输入/输出通信。
在一般定义中,该算法只是一个配方(指令序列)。我认为如果不知道可以使用的指令集或操作,就无法想到算法。数学运算是关于计算的,那么包括一个名为“ 加热烤箱 ” 的步骤的算法不是数学算法,但是您可以将其交给厨师,因为他知道如何执行。
然后,您可以创建一台可以执行X,Y,Z .....的机器,它们可以在您的算法中用作指令。但是,如果它们都是关于封闭计算的(实际上是非交互式确定性数字小步计算),则可以证明您的计算机与Turing Machine等效。但是,如果您针对其他类型的计算(连续值或交互式计算 [但是我不确定它们是否真的是另一种类型的计算])或什至没有计算任务,您可以想到可以执行它们的机器。
这个问题和答案也很有趣,可以更广泛地了解算法。
通常,将算法设计为针对某些特定问题,同时最小化某种程度的“成本”。从历史上看,许多算法是基于以下假设设计的:在许多体系结构上,常见操作的相对成本会相对相似,因此,某些典型机器运行一种算法会比另一种算法运行更好,然后在大多数典型机器上,前一种算法会最糟糕的是,仅次于后者。随着时间的流逝,这种假设不再像以前那样成立。
例如,过去通常认为程序从内存中读取内容所需的次数比要读取的内容的位置更为重要。读取内存中彼此靠近的东西要比读取相距较远但显示得不离谱的东西便宜。但是,由于主CPU速度以远远超过内存速度的速度增加,因此访问顺序的重要性已大大提高。如果前一个程序的95%的内存提取产生L1缓存命中,而后一个程序的大多数内存提取生成缓存未命中,则一个程序执行的指令数量可能是另一个程序的十倍,但运行速度仍然更快。
此外,某些种类的与并发相关的算法对一个处理器内核写入内存的数据何时会被其他内核“看到”做出各种假设。许多处理器具有各种读取和写入内存的方式,但成本各不相同,并且保证了可见性。某些算法在可以“免费”满足可见性要求的体系结构上会很好用,而在那些保证所需的指令昂贵的体系结构上效果不佳。实际上,在某些体系结构上,只能通过将执行限制在单个时分CPU内核上来确保某些与并发相关的算法能够正常工作(这当然会妨碍使用并发算法)。
许多答案都缺少这样一个事实,即可以用从体系结构抽象或与体系结构直接相关的术语来定义算法。算法必须是明确的,但仍有一定程度的空间来具体化。
可以使用独立于体系结构的伪代码轻松描述将字符串转换为全大写的算法。但是与此同时,没有什么能阻止您描述专门针对x86体系结构将字符串转换为全大写的算法。所要做的只是x86组装作业。(您仍然可以用伪代码执行此操作-只是与该体系结构有关的伪代码!)问题实际上是专门针对x86体系结构执行的,这并不意味着您不再拥有解决该问题的算法。
这取决于定义算法要解决的问题。如果该算法解决的问题与体系结构无关(并且假定通过描述或组合算法的方式无法撤消该问题),则该算法与体系结构无关。这个问题可能是理论上的问题,也可能是黑板上的问题,也可能是非常具体的体系结构。在后一种情况下,该算法将仅限于使用该体系结构。
它们在问题的不同上下文方面有所不同。算法是解决问题的步骤的集合。从理论上讲,此问题的上下文可以是任何东西。因此,解决问题的算法实际上可以依赖于我们可以想象的宇宙上的任何事物。让我用一个例子来阐明。假设您被赋予一项任务,
构造一个算法,在多核可用时将负载分配到多个核。
现在您能想象您的算法是否依赖于体系结构?当然可以。