1
27
我想说这不值得。我使用的软件可以进行实时3D渲染(即,在没有GPU帮助的情况下进行渲染)。我确实广泛地使用了SSE编译器的内部原理——许多充满了
我的经验是,优秀的现代优化编译器在复杂的微级优化方面非常有效。他们将进行复杂的循环转换,如重新排序、展开、管道化、阻塞、平铺、阻塞、裂变等。他们将安排指令来保持管道的填充,对简单的循环进行矢量化,并部署一些有趣的位旋转黑客。现代编纂者是令人难以置信的迷人的野兽。 你能打败他们吗?当然,考虑到他们选择启发式使用的优化,他们有时肯定会出错。但我发现,从更大的角度来优化代码本身要好得多。我是否以最适合缓存的方式布局数据结构?我是否在做一些不正统的事情来误导编译器?我可以重写一些东西给编译器更好的提示吗?我最好重新计算一些东西而不是存储它吗?插入预取是否有帮助?我在某个地方有错误的缓存共享吗?编译器是否认为小代码优化不安全,但在这里还可以(例如,将除法转换为乘法的倒数)? 我喜欢和编译器一起工作,而不是对抗它。让它负责微级别的优化,这样您就可以专注于Mezzo级别的优化。重要的是要了解编译器的工作原理,以便知道两个级别之间的界限在哪里。 |
2
10
唯一可能的答案是:是的,如果有相关和有用的性能增益。 我应该猜的问题是:在C/C++程序中使用汇编语言能获得有意义的性能增益吗? 答案是肯定的。 你得到一个 有意义 在过去的10-20年间,随着库和编译器的改进,性能的提高可能会减少,但对于像x86这样的体系结构,尤其是某些应用程序(特别是与图形相关的应用程序)中的手动优化,可以做到这一点。 但就像任何事情一样,除非你需要,否则不要优化。 我认为,在大多数情况下,算法优化和编写高效的C(尤其是)将以比用汇编语言重写花费更少的时间创造更多的性能增益。 |
3
6
困难在于,考虑到现代CPU的体系结构,您能否比编译器做得更好地优化呢?如果您设计的是一个简单的CPU(例如用于嵌入式系统),那么您可以进行合理的优化,但是对于流水线结构,优化要困难得多,因为您需要了解流水线是如何工作的。 因此,考虑到这一点,如果您可以进行这种优化,并且您正在处理一些探查器告诉您速度太慢的事情,并且这是一个应该尽可能快的部分,那么是的优化是有意义的。 |
4
5
也许吧这完全取决于个人计划在知道之前,您需要一个配置文件,它是通过配置文件工具获得的。有些程序把所有的时间都花在等待数据库上,或者只是在一个很小的区域内没有集中的运行时。如果没有这个,组装就没有多大帮助。 根据经验法则,90%的运行时发生在10%的代码中。你真的想要一个非常强烈的瓶颈,并不是每个程序都有这个瓶颈。 而且,现在机器速度如此之快,以至于一些低垂的水果被编译器和CPU内核吃掉了,可以说。例如,假设您编写的代码比编译器好,并将指令计数减少一半。即使这样,如果您最终做了相同数量的内存引用,并且它们是瓶颈,那么您可能无法获胜。 当然,可以在以前的循环迭代中开始预加载寄存器,但编译器可能已经在尝试这样做了。 学习汇编实际上更重要,因为它是一种理解机器真正是什么的方法,而不是一种击败编译器的方法。但是试试看! |
5
4
有一个领域仍然定期进行装配优化- 嵌入式软件 . 这些处理器通常不是很强大,并且有许多架构上的特性,编译器可能无法利用这些特性进行优化。这就是说,它仍然应该只在代码的特别紧凑的区域内完成。 和 它必须有很好的记录。 |
6
4
我假设您已经对代码进行了分析,并且找到了一个占用大部分时间的小循环。 首先,尝试使用更具攻击性的编译器优化重新编译,然后重新分析。如果您已经任意运行了所有编译器优化,并且仍然需要更多的性能,那么我建议您查看生成的程序集。 在查看了函数的汇编代码之后,我通常会做的是查看如何更改C代码以使编译器能够更好地编写汇编。这样做的好处是,我最终得到的代码可以在我的处理器上与编译器一起运行,但是可以移植到其他环境中。 |
7
4
对于编写应用程序的典型小型商店开发人员来说,性能增益/工作量权衡几乎从不证明编写程序集是正确的。即使在装配速度可以使某些瓶颈速度翻倍的情况下,这种努力也常常是不合理的。在一家大公司里,如果你是“表现型员工”,这可能是合理的。 然而,对于一个库编写者来说,即使是小的改进也常常是合理的,因为它为最终使用库的数千开发人员和用户节省了时间。对编译器编写者来说更是如此。如果您能在核心系统库功能中获得10%的效率胜利,那么就可以真正节省分布在您的用户群上的数千年(或更长)电池寿命。 |
8
2
当然可以! 这里是一个CRC-32计算的演示,我用C++编写,然后用VisualStudio在X86汇编程序中进行优化。 应在程序启动时调用initcr32table()。 calcCrc32()将计算给定内存块的CRC。 这两种功能都是在汇编和C++中实现的。 在一个典型的奔腾机器上,你会注意到汇编程序CalcCRC32()函数比C++代码快50%。 汇编程序实现不是MMX或SSE,而是简单的x86代码。 编译器将永远不会生成像手工编制的汇编程序代码那样高效的代码。
|
9
1
我想说,对于大多数人和大多数应用程序来说,这是不值得的。编译器非常擅长精确地优化为其编译的体系结构。 这并不是说优化装配并不是没有必要的。许多数学和低级密集型代码通常通过使用特定的CPU指令(如SSE*等)来优化,以克服编译器生成的指令/寄存器的使用。最后,人类精确地知道程序的要点。编译器只能假设这么多。 我会说,如果您不在您知道自己的程序集将更快的级别上,那么我会让编译器做这项艰苦的工作。 |
10
1
不要忘记,在程序集中重写会丢失可移植性。今天你不在乎,但明天你的客户可能会想要你的软件在另一个平台上,而那些组装片段会真的伤害他们。 |
11
1
好答案。如果你已经做了,我会说“是的” performance tuning like this 你现在处于
编译器不知道你所知道的一切,所以它们是防御性的,不能利用你所知道的。 作为一个例子,它们以一种通用的方式编写子例程入口和出口代码,不管子例程包含什么内容,都能正常工作。另一方面,您可以手工编写一些小的例程,这些例程可以省去帧指针、保存寄存器和类似的东西。你冒着bug的风险,但有可能击败编译器。 |
rookie · 检查函数模板的所有参数包参数是否属于int 1 年前 |
ivaigult · -W转换和隐式字符串到布尔类型转换 1 年前 |
rainer · 后台插入程序的初始化 1 年前 |
Community wiki · 以理智、安全和高效的方式复制文件 1 年前 |
Shefali Kanaujia · 对C中向量的向量进行排序++ 1 年前 |
Ma Joonyoung · 粗粒度和细粒度链表的时间比较 1 年前 |