Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
汇编语言能使用C编写的程序更快吗?_C_Assembly_Performance - Fatal编程技术网

汇编语言能使用C编写的程序更快吗?

汇编语言能使用C编写的程序更快吗?,c,assembly,performance,C,Assembly,Performance,我正在用C语言编写程序,需要大大加快速度,因为这是性能评估。所以我很好奇汇编代码是否能使C程序在任何级别都更快?若我用汇编语言替换部分C代码,是否可能缩短程序的运行时间?例如,巨大的循环\ 谢谢 当且仅当以下一项或多项为真时,用汇编替换C代码可以使代码更快: 你的编译器正在生成糟糕的代码 您忘记启用优化 您正在替换的C代码效率异常低下 您正在编写的程序集正在使用编译器无法使用的CPU功能,例如向量操作或特定于任务的原语(如加密加速)。请注意,一些现代编译器也可以自动将代码矢量化,尽管并不总是很好

我正在用C语言编写程序,需要大大加快速度,因为这是性能评估。所以我很好奇汇编代码是否能使C程序在任何级别都更快?若我用汇编语言替换部分C代码,是否可能缩短程序的运行时间?例如,巨大的循环\


谢谢

当且仅当以下一项或多项为真时,用汇编替换C代码可以使代码更快:

你的编译器正在生成糟糕的代码

您忘记启用优化

您正在替换的C代码效率异常低下

您正在编写的程序集正在使用编译器无法使用的CPU功能,例如向量操作或特定于任务的原语(如加密加速)。请注意,一些现代编译器也可以自动将代码矢量化,尽管并不总是很好


如果前面的条件都不成立,您将浪费时间。

在汇编程序中简单地重写C代码极不可能加快速度。事实上,它有更好的机会放慢速度。现代编译器非常擅长生成尽可能高效的汇编代码—用C编写的算法表达式。只需确保启用编译器的优化选项

性能增益最有可能通过各种策略获得,这些策略可用C表示:

循环展开 消除不必要的计算 预计算值 用更高效的算法替换算法 用更高效的数据结构替换数据结构 注意并重新组织计算以实现它
许多其他技术也可以应用,但如果不了解您的问题的更多信息,就不可能说什么可能适用。

一个好的编译器会在优化方面做得很好,因此,即使您是专家并且愿意花时间为某些任务找到最佳的程序集,您通常也不会获得太多收益。对于一些内部循环来说,手工编写的汇编可能是值得的,比如在一个游戏中,循环每帧每像素以60fps的速度运行一次。但是如果你对CPU不太了解,你也可能使它比编译器更糟糕,因为最佳汇编并不总是直观的。现代CPU和内存体系结构非常复杂

对于99%的性能问题,请忘记这一点。对于剩下的1%,在进行其他优化之前不要考虑它,请参阅下面的内容。否则,您很可能没有要优化的正确内部循环。手写组装是最后一步,例如,在将所有其他内容优化到极限后,再挤出几个FPS

相反,对于性能,首先要做的是找到瓶颈:分析和基准测试。它还需要知道您是否真的改进了任何优化,或者当您忘记考虑一些细节时,它们是否会使事情变得更糟,这在优化时并不少见

然后,提高性能的主要方法是选择正确的子算法和数据结构。例如:从插入排序切换到简单快速排序可能是一个巨大的改进。除非对数据进行排序,否则将受到巨大的惩罚。然后,您可以进一步改进快速排序,通过对排序后的数据进行随机化,在运行时调整算法(如果您知道它已排序),切换到合并排序,等等。这是利用数百位非常聪明的计算机科学家几十年的辛勤工作,他们发明了常用的算法


然后是优化您自己的算法,降低其复杂性,例如使用技术,通过正确组织数据,使用正确的数据结构…

如果您确信已经尽可能优化了C级代码,那么您可能希望研究如何利用大多数现代微处理器固有的并行处理能力。您可能需要查看OpenMP

这是假设消耗所有程序时间的特定算法是可并行的。。。如果你真的是硬核,你可能会研究OpenCL或CUDA,以利用你的GPU的大规模并行处理能力,假设你的平台有一个。。。。你说的那个大循环。。。是否可以将问题拆分,以便多个for循环可以同时处理该问题


如果可能的话,在特定的程序中采用上述方法,而不是试图用手工优化的汇编来击败编译器,那么实现目标的可能性要大得多。

您提出的每个问题的简短答案都是肯定的。然而,这并不意味着用汇编语言而不是C语言编写部分代码是值得的

有许多问题你应该先问自己,然后自己回答

你的程序写得够快吗

你分析过它吗?也就是说,你知道瓶颈在哪里吗 在你的节目里? 关注那些能让你获得最大回报的领域

在汇编语言中编写部分代码之前,C语言中还有算法上的变化吗 你能做些什么来加快速度?再次强调,关注那些能给你带来好处的领域 你的钱最划算

使用更快的硬件加速是否可行

您了解各种编译器优化设置吗?你使用的是相关的吗

您是否分析了编译器生成的内容

有优化的空间吗

你的优化目标现实吗


如果在所有这些之后,您仍然认为您的程序需要一些汇编,请尝试它。请记住,即使您可以在汇编中编写一些东西,但这并不自动意味着它将比编译器生成的更快。毕竟,编译器也会生成程序集。

我不同意那些认为编译器优化不能通过在程序集中挖掘来改进的人。以上关于改进算法的所有建议都是有效的,我认为这是重要的第一步。然而,一旦您有了一段代码,并且您已经用更高级的语言尽可能地对其进行了细化和优化,那么在使用dis汇编程序处理代码以查找代码中是否存在任何瓶颈时,可能还有一些实用程序

另一个观察点是,不同的语言甚至同一语言中的编译器在可执行文件中生成结构不同的系统代码。如果您针对的是特定的体系结构,那么您可能能够削减一些fat,但是您必须非常明确地知道需要导入哪些例程,操作系统希望您执行的所有操作,以及禁止您执行的操作


关于减少运行时的大小,您有一个正确的观点。如果您只使用一个特定的例程,比如puts,并且包含了整个conio和stdio,那么您将能够通过在混合中引入程序集而不是使用标准库来消除不使用的大量代码。但脱离标准遵从性可能会有问题;当预期的行为开始失败时,用户将能够立即判断您的软件是否执行不良。例如,通过管道将程序输出传输到更少或更多的程序中的能力—使用BIOS例程可能会更快,但当您对操作系统冷淡时,这种能力就会失败。

在assembler中重新编译东西能使您的程序更快吗?对明显更快?这取决于瓶颈在哪里

使用现代处理器,保存指令并不一定能节省处理时间。调度操作以充分利用重叠执行可能会做得更好,即使涉及更多指令。这些规则很复杂,根据我的经验没有很好的记录,而且每个处理器的规则都不同。。。并且可能比人类程序员更适合机器生成指令。处理器是用来运行机器生成的代码的!更干净、手工编制的代码可能看起来更漂亮,但运行速度可能不会更快:-

对于关键代码的小片段,人类可以更好地以特别适合任务特殊需要的方式使用特殊目的指令。如果人类能够利用问题的特殊性质,他们也可以做得更好。在汇编程序中,人类甚至可以推动通用指令,从中获得更多信息。使用分支预测器会有所帮助,而且人类可以知道更多关于代码将要做什么的信息,而不是编译器可以从编写的内容推断出的信息。类似地,人类在向缓存管理提供预读提示等方面可能会做得更好。简言之,人类在无法期望通用代码生成产生最佳结果的专业领域仍然可以做得更好

在较大的代码片段中,不受ABI约束的人可能会做得更好。人类可以将密钥信息分配到多个函数的寄存器中,并让一些函数以方便调用方的方式获取参数并返回结果,而不需要在调用之间一直进行混洗。此外,考虑到问题的全局性,人类可能更善于分配内存中的内容来帮助缓存。简言之,人类仍然可以从更广阔的角度看待问题,做得更好

然而,所有这些都不会便宜!而且,可能有必要尝试多种手动优化代码的方法,并进行一些仔细的测量,以确保它确实更好

当然,这一切都是假设您正在为一个大处理器编写—您没有指定。如果你是为一张小小的照片而写,比如说,旧的规则适用

当然,还有 e关于代码优化的最古老规则:

不要这样做:找一个更好的算法 不要这样做:找到更好的数据结构 不要这样做:重复1和2 不要这样做。。。除非你有一段对运行时间至关重要的代码。。。即使这样,也只能优化重要的部分。
相信我,作为一名汇编程序员,说这些话让我很痛苦!但是,您需要一种特殊的问题,以使精心编制有效的汇编代码所花费的时间和精力变得值得。

可能,尽管优化编译器现在相当聪明。你可能打不过他们。首先优化你的算法。用C编写的快速排序将大大超过用ASM编写的冒泡排序。是的,但由于编译器无法执行优化,也可能会使排序速度变慢。谁更适合编写优化程序集,您还是编译器?而是优化你的算法。对C和ASM给出一般化的建议是不切实际的。用具体的术语定义问题的性质。你的问题太抽象了,无法回答。也许你应该告诉我们更多关于你试图优化的代码。。。这是一种可以分解为并行组件的算法吗?通常改进算法是最有价值的方法。希望通过asm获得神奇的收获通常以失望告终。编译器的工作相当出色。+1,完全正确。我想说,现在用汇编语言编写代码是很没用的。编译器在这方面做得更好。更不用说,很难判断编译器何时实际生成了糟糕的代码。@FilipeGonçalves我想,如果您的电源或内存限制非常紧张,这仍然有点有用。@Cubic Correct。但请注意,我只是说,在这些情况下,使用汇编将使您的代码更快—大小限制完全是另一个问题。如果您需要比openMP更精细的解决方案,我建议使用pthread。一旦您学习了pthread,您就会自动地对C有了比以前更深刻的理解。