五千年(敝帚自珍)

主题:【讨论】解释执行类代码的性能有无可能达到甚至超过本机编译代码 -- 老兵帅客

共:💬64
分页树展主题 · 全看首页 上页
/ 5
下页 末页
            • 家园 @@

              这样说吧, 能在计算机上实现的东西,

              没有什么是C编译不出来的, 什么动态管理爱...blah..blah..blah..

              编译器自己还是C写的讷. 自己编动态管理不就完了...

              动态管理很神秘么?

              • @@
                家园 C语言程序编译以后就没有Meta Data了

                因此是无法作动态优化的。

                • 家园 你们的优化到底是什么概念爱?

                  do loop 等结构的并行处理?

                  寄存器的利用?

                  内存使用的重新分配?

                • 家园 Metadata不能加进去么?就像调试器版本的那样
                  • 家园 调试器用的和动态分析/优化用的Meta Data是不一样的

                    供调试器使用的带调试信息程序不过是多了些中断点和行号信息以便于走单步、看变量和设断点,再多的就没有了。而动态分析/优化所使用的Meta Data实际上是包含了中间语言(某种相对高级语言)的程序流信息,这样可以根据Profiler结果来对中间语言的程序流进行优化,这样优化的效果往往要比直接优化汇编码的效果好得多。

                    • 家园 关键在于这种程序流的信息是否只有VM机才能提供

                      而编译器,或者经过改进的编译器就不能提供?

                      Debug器可以在程序执行期间动态 Track 变量,堆栈,

                      为什么就不能Track Hotspot? 现在他们没有这么做,

                      不意味着以后就不可以吧?

                      • 家园 不知道是不是可以这样说:C/C++编译好的程序就是CPU执行的具体指令了。

                        你不管如何运行,他就是他了。所以一个程序你不管运行多少遍,可执行文件依然如我,不会丝毫改动。(你也没法改动了)

                        而Java的byte code和.NET的IL不是机器指令。是一种中间语言,在运行时由JVM或是CLR临时翻译成机器指令。这个过程是one to many的关系。一段byte code可能在第一次翻译的时候,质量很低,但经过一段时间,翻译的质量就会提高,甚至超过C/C++静态编译的质量。

                        理论上讲,JVM和.NET有C/C++拥有的一切静态信息以及更多的动态信息。对一个长时间运行的程序而言,编译的开销会逐渐消失。理论上因该可以产生更好的机器代码,取得根好的性能。当然,程序最终的性能还有好多其他因素,比如内存管理方式的不同会造成性能上的差异。

                        • 家园 回复

                          一。目前标准的C/C++程序编译以后所得到的可执行文件只是一个二进制执行映像,而不存在媒体信息,因此是不可能自行改动代码运行顺序或者优化的。但是记忆中确实存在过解释型的C/C++环境(它有提示符OK,从图片上来看很像是古典的Basica),因此应该有对应的中间码表示和中间码到机器码的转换。

                          至于机器代码自修改,主要是通过汇编码来实现,除了病毒这类变态应用以外,主要是用在极度节省内存的环境中。

                          二。对于JVM/CLR这类现代VM来说,中间码到机器码的转换过程的确存在一个学习时期,而且这个时期的确可以提高转换质量,从而提高VM的运行效率,甚至在局部做到理论上的最优化,从而超过静态编译优化器所能够做到的程度,但是在全局范围内的最优化将需要很长的运行时间,这样这项技术的适用范围将受到限制。

                        • 家园 二进制代码不能变化似乎也不是绝对的吧

                          最初的编译器产生的code是直接映射到内层物理地址的,然后

                          有了动态连接,动态库等技术

                          现在你说的这个one to many的关系必然也是有限的,

                          编译器不能事先作出多个翻译方式,在运行期间作出

                          优化选择?

                          • 家园 回复

                            一。阿康所说的多准备几个分叉是不现实的,因为执行路径树会迅速地膨胀从而导致可运行代码量的极度膨胀,这样稍大一些的程序会编译出大的不可想象的可执行文件来的,因此这个方案是行不通的。

                            二。动态编译的好处就是可以极端逼近理论上的最优化可执行代码,从而超过静态编译,因为后者缺乏运行经验,因此不可能得到理论上的最优化可执行代码。当然这个过程需要足够的时间和开销,因此比较适用于长时间运行的代码。

                            三。代码优化本身最好是在机器代码之上的某个合适层次来进行(机器代码级别太低了,很难做到比较大范围的优化),Java Byte Code/.Net IL正好提供了这个层次,这就是现代Meta Data对传统静态编译的优势所在。


                            本帖一共被 1 帖 引用 (帖内工具实现)
                            • 回复
                              家园 Bingo!

                              That's what I am talking about!

                              好费劲啊!

                              点看全图

                              外链图片需谨慎,可能会被源头改

                              • Bingo!
                                家园 恐怕还没结束

                                从下面这个链接:http://www.cchere.com/article/216340 可以看出沟通是多么困难的事情。

                                另外,Java/.Net的这类优化只限于可以长时间反复运行的程序,在这部分程序中,它们确实可以达到比静态编译更好的优化效果;但是对于其它类型的程序,Java/.Net最多只可以做到接近于静态编译的程度,这样总体效果如何主要依赖于程序的类型,而且对于桌面应用来说,效果不会很好。

                          • 家园 如果你有多个可执行代码,那么CPU Load哪一个呢?

                            .NET/Java的在一个时候只会有一个机器代码让CPU执行。而这个机器代码在一段时间后可能会不一样了。这就是“动态”。就像我们所说的“兵无常形,水无常势”一样。

                            C/C++一旦编译完成,就是“done deal”了。你Source code都没有了,你怎么再优化,再重新编译出更好的机器代码。

                            现在CPU倒是在不停的努力,试图作一些预测和out-of-order的执行。这些CPU的新能力又会反过来影响compiler的发展。

分页树展主题 · 全看首页 上页
/ 5
下页 末页


有趣有益,互惠互利;开阔视野,博采众长。
虚拟的网络,真实的人。天南地北客,相逢皆朋友

Copyright © cchere 西西河