加入要在x86里加入一块fpga,在运行ps时即时android x86arm编译器为图像处理器,在运行3dsmax时,android x86arm编译器成3

在 CPU 中集成 FPGA 等可编程电路的想法如何?
首先说明一下这里说的FPGA可以被应用程序以某种方式编程、使用。下面是个人陈述时间~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~这个想法是异构计算的一种吧。异构计算中“异”的部分一般是指用CUDA、OpenCL、DX Compute等API利用的GPGPU或是不同指令集的CPU。不同指令集的CPU暂且不提(于PC意义不大),单就GPGPU而言,是有着比较严重的局限性的。这个局限性表现在于:正如它诞生的理由一样,它只适合计算密集型应用。而对普通用户而言,除了游戏,似乎没有其他对计算能力有如此渴求的应用。因为这个致命的缺点,异构计算吼了这么多年,GPGPU从来没有大规模推广过, Windows 8 modern task manager也没加入GPU使用率,显卡也从没摘过“显卡”的帽子o(╯□╰)o与之相比,FPGA便有更广阔的应用场景。其与CPU及ASIC比较,FPGA在通用性与性能两者中都处于一个适中的位置,可以作为当前计算机体系结构的补充。可能的应用:1.实时CPU机器码-&FPGA原语综合。操作系统可以实时检测目前哪一些函数正被频繁调用,将其翻译后在FPGA上综合。2.高性能需求应用为其编写HDL模块,运行时综合以实现加速,如网页服务程序、数据库引擎等。3.获得不具备的硬件功能,如新一代CPU的新增指令集,更大的Cache,TPM芯片。(开源硬件?4.在FPGA上实现操作系统内核。可以让微内核概念变得真正可行,因为如果FPGA模块可以掌控外围硬件的话,syscall便不需要进行状态切换。5.作为一个监视系统来监视宿主系统的运行状态。~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~可行性分析就交给你们了=_=
按投票排序
简单说两个CPU+FPGA问题:1. 楼上提到的die size。高性能cpu和fpga以及片上cache都是面积需求大户,现实的die size一定,谁用多少需要架构探索,性能此消彼长。2. FPGA如何使用。目前高位综合效率较低,而让普通软件开发人员用HDL写加速硬件,学习和开发成本太高。FPGA和processor(cpu,dsp,gpgpu)的玩法完全不同,现代编译器发展成果很难直接用在FPGA上。有一支研究在FPGA上实现虚拟CGRA,他们希望同时获取fpga和processor两方面优势。现状:1. FPGA SoC产品Xilinx和Altra都有。比如Zynq系列内嵌ARM 1G以上多核processor加大规模FPGA逻辑。目前很多业内学界的FPGA+CPU应用研究都是使用这款芯片。2. 让普通应用软件开发者更容易使用FPGA,是这几年FPGA领域的首要任务。高位综合目前看来比较难达到好效果,为GPU而生的opencl框架虽然也支持fpga但效果也有限。google、微软、xilinx也在探索面向应用的高度可配置的专用硬件系统(非processor)。总结:FPGA很自由,你可以用他做任何数字逻辑,还有大量片上dsp,block ram,甚至可以动态重编程。性能比processor高几十上百倍,比asic低十倍左右。FPGA行业之前集中资源发展硬件,现在硬件架构基本稳定,正是开始研究拓宽应用的阶段。楼主的一些想法业内也正在探索,目前要说商用成果还言之尚早,但前景可观。很有可能是打破processor独统世界的技术。
在未来,FPGA可以见到的玩法应该是这样的:0. FPGA的频率大约只有CPU的1/8 - 1/10;1. L3 cache的访问能力,在L3一级的总线上提供更加同步信令;这样可以保证FPGA有足够的带宽和统一寻址能力;2. 提供基本单元(也就是DSP。因为FPGA很难做到比ASIC快),比如浮点运算单元,不用太多;如果有延迟更低的互联总线,也可以削弱这部分的设计。3. Intel提供Synthesis SDK,解决电路综合软件的License Fee过高的问题;4. Stacked Package,这样有足够的空间可以放置FPGA的晶体管;5. 软件在编译之后的可执行文件会存在.fpga section,OS会在软件运行前装载到FPGA上。另外,FPGA设备应该是一段时间内独占的,因为切换成本太高。6. 高级语言编译到FPGA不是非常现实,但是可能会出现比Verilog更高级一些的语言。另外,FPGA的优势在于可以通过Pipeline提高Throughput,并做Latency Hiding,而不仅仅是并行化。
谢邀先,这个问题很长,慢慢答,首先看了前面的答案,大多数答非所问。只有 @浪客 的答案(是这么引用么)切中部分问题。至于其他提到的东西,基本都已经是常用架构了。比如fpga做相机,那就是把工业相机的方案移过来而已。工业相机一共两类方案,一个是fpga,一个是dsp,dsp还分为通用如达芬奇,或者专用的例如所谓的机芯(套片)。fpga相对高端些。不过直接用来做消费电子相机有点夸张了,基本上不是成熟的商业模式,不赚钱是肯定的了,拿到手里被用户摔基本是必然的。至于cpu加fpga,挂pcie也好,挂rapidio也好,或者直接flex bus, 异步ram接口都可以,都有成熟模式,做里头做外头都有成熟的样例,怎么封装其实无所谓,就是钱的问题,所以其他的都没答到点子上。oracle的那个只是说fpga实现指定软件加速,当然有一定灵活性啦。这个大家都有,Fb,google 都可能有,暴雪,摩根也有。就是硬件加速嘛。但这个不是题主的问题点……………………题主想要的东西是一种半生物,而不是一台大家在讨论的硬件产品。生物的基本要求是能生长,能繁殖。题主要的东西不需要繁殖,但实实在在的要自动发生物理形态的变化,类似生长或者进化,目前还属于科幻领域。…………题主设想是一个强大的编译器,可以将软件代码中部分适用于硬件加速的部分提取出来进行硬件加速。首先这涉及到任务划分的问题,哪些硬件加速,哪些软件实现。这目前一般人为判断,人工智能还没发展到这地步。即使假设到了那一步,由于软件可以并发多任务执行。当a任务执行时,并不知道几分钟后b任务要干什么。因此一种综合结果对a最优可能导致b无法执行,当任务更多时很可能就因为已执行任务的负载导致无法进行新任务。此外,由于硬件加速会改变指令周期,硬件加速实现情况变化(由于优化情况与历史有关),软件无法判断指令完成情况,只能设定特定的同步路径,这实实在在需要物理存在的路径来实现。由于现有的cpu通信路径数量有限,而软件任务数无限,因此板卡需要额外长一些线出来才行。这就是生长。另外,硬件综合需要很大的计算量,且不说现有cpu可以短时间内综合出结果,就算系统跑起来后,为了综合效果,需要将所有在运行的进程全部重新加速,就意味着cpu上的软件需要全down掉。诚然fpga可以在线重配,部分重配。但是每次配置都需要秒级时间。每个软件算法在每个阶段都有可能需要加速,那每次都重配你的系统要多不稳定。所以fpga和gpu一样只适合对已知算法进行加速,不适合进行未知操作的实时变更。最理想的操作就是通过一条总线将一个完整任务的数据打包流过来,处理后再流回去。
一般程序员写不好 HDL,那东西的思维和编程乃至单片机都完全不同。不过 AX 二厂最近都有弄 OpenCL 的 SDK……
我们终于要迎来CPU中毒的时代了。只要中毒,你就死的透透的~~
非常好的问题。我不是研究CPU和系统构架的,所以我会从市场的角度来简单分析下。 问题中所说的异构提出的很早了,那个时候好像只有CPU,没有ARM。所以大家的视角也只是集中在这里,最近几年,智能手机的爆炸性激发了ARM和它小伙伴们蓬勃的爆炸性发展。相信你们能懂我的意思。现而今,如果非要CPU+FPGA,可能还是没有人会做,跨越很大,我想不到有什么试用环境能激发芯片公司去投入巨额资金做研究。不是不能搞定,是搞定了不知道卖给谁。与其开发一个市场不确定性很大的新构架,不如在旧有的构架上添枝加叶,多弄几个核,提高频率,增加缓存,功能大大溢出需求,反正世界上就2家CPU,爱买不买。突然之间,智能手机火了,世界变了。intel的现状我们都知道,不扯了。也许以前CPU行业是技术导向,但是现在这几年可不是技术人员打算做什么,而是这个世界需要什么。举个例子:华尔街的高频交易用的是FPGA而不是传统意义上的服务器+软件。计算公式相对固定,逻辑程序相对固定,只要求速度和稳定性的场合,给人用的机器显然不适合。大数据、云计算、物联网、XXX管它什么概念,这是全新的使用场景,也许FPGA里边嵌个ARM会更适合呢? 个人感觉做Streaming就很合适啊再透露点小道消息吧,某著名消费类电子产品大厂下半年会出个新型号相机,一颗FPGA,图像处理的算法,各个硬件部分的驱动,几乎所有程序都扔在FLASH里,用的时候往FPGA里拽。挺奇怪的吧,和传统意义上的系统完全不同了。
问题很有意思,但是可能实际应用环境不大。一般是FPGA 去集成CPU,CPU集成FPGA 成本不优势
这个叫可重构。。
题主的问题约等于:现在的原子弹在烧烤界一直没有流行起来,如果把炉子和激光枪结合起来会不会更有前途?
FPGA塞进CPU,如果要它还是一块FPGA,你还是要进行编程。那么在现在FPGA都有PCI-E接口的情况下,我认为塞进去意义不大。因为你塞进去它还是FPGA,它还是独立于CPU核心的,它们还是需要总线连接的,现在看来,FPGA和CPU之间靠PCI-E速度已经足够了,以后就不知道了,不过现在这样分开来也有好处,扩展性好啊。
可参考2012英特尔嵌入式平台的那个芯片,这个芯片将一个atom处理器和一款altera中高端(型号忘了),通过pcie总线连接,并封装到同一块封装内。即看起来是同一块芯片。当初据说Intel想和altera有“更深入的合作”,集成到同一硅片上之类的,但是会涉及一些涉密技术问题还是什么的,还是Intel有并购altera的意思什么的(野消息,不对的话请忽略),总之合作不是很愉快,之后好像就没再出x86和altera集成的芯片了。但是现在altera有集成有arm硬核处理器的芯片。这种结构一方面是可以一些外设动态配置,减少了桥芯片的使用,另一方面可以软硬件协同设计提高计算性能吧。不对的地方应该很多,致信度不高,当段子吧。 补充最近用 altera 的 cyclone v 系列芯片,集成了 cortex a9 双核的处理器,用qsys搭建系统,FPGA 和 arm 有高速总线桥连接,使用很方便。
嵌入式某些轻量级soc有这样做的
已经有了啊。
如果你要增加FPGA的通用性,到最后也只是重新复制了一遍CPU的功能而已,如果这“通用”的FPGA能干CPU的活,无非也就是把microarch用软件来实现而已。CPU+FPGA在SOC里有应用,无非就是把动态的软件放CPU上跑,静态的运算放FPGA上跑。如果要对FPGA进行动态修改,片上资源肯定不够HLS用的
看看Xilinx最新出的MPSoC架构,再看看题主的提问时间。觉得题主是一个先知先觉的人。哈哈。
感觉题主是学软件的吧。1.2 实时综合性不可能,PC硬件吃不消,EDA license买不起。芯片设计公司的投入,至少三分之一在EDA license上面,一般用户用不起。当你浏览网页的时候会不会花一个小时去等实时综合的结束?1.2.3.从工艺的角度上,die size受不了。多出来的钱不如配更好的电脑。没有公司这么傻,做出来的芯片巴掌大,这是勋章还是chip。4.5 纯属yy,如果chip像你说的这么容易做出来,大家都用fpga就好了。
FPGA级别的可重构计算不同于GPU级别的可重构计算,软件瓶颈严重。目前的操作系统不支持由软件实时修改CPU指令集的计算模型,所以FPGA部分不能被操作系统当作CPU,只能被当作外设。现代的操作系统禁止程序直接访问硬件,所以访问FPGA部分还要经过驱动程序。结果,每次修改FPGA部分都要重新安装新的驱动程序,不能边用边改,更不能多个应用程序共享FPGA部分。以上各种兼容性问题基本否定了可重构计算跟通用操作系统结合、用FPGA加速应用程序的可能性。修改操作系统内核的复杂度和受到的历史制约可能比让应用程序开发者从头学习HDL编程还要大。楼上所述的各种现有异构芯片的目标市场都是典型的嵌入式应用。在这些场合里软件和硬件一起被开发,然后软件一次性固化在硬件里基本不再改动。尤其是FPGA部分作为一个功能固定的外设不再改动。可重构计算用于消费类电子可能唯一的案例是Creative在2009年推出的的Zii,stem cell computing “干细胞计算”。目前还没倒但是非常小众,只用来制造一些规格特殊的多媒体设备。
Intel出过基于atom的型号,直接集成一块不大的FPGA。不过据说并不给民间使用,而是给定制用户使用的。Xilinx也有对应产品,不过集成的CPU核心是Cortex-A9的,貌似是四核的。然后配一大坨FPGA。Altera记不清了。Atmel也出过AVR+FPGA的芯片。总之这类产品是有的。不过因为FPGA的开发难度有些高,所以恐怕普及会有很大难度。要知道GPGPU的应用仍然没有大规模普及,更何况难度更高的FPGA。
您提到的第一条好像在processor的high-level synthesis的相关文献里有做过类似工作,那个synthesis的工具叫做LegUp。只不过这个需要用户自行用c来写加速器,不能自动生成。文献的地址在这里:这个工具可以实现把C转化。既然您想要把CPU机器码转化,这一类甚至能直接转化C的工具应该能对您的设想有帮助吧。
目前cpu+fpga的应用主要还是把fpga做高速并行处理单元用,用来做控制的很少。两个放在一个封装的只是听说过有产品,没有看过有谁用过。&&1.实时CPU机器码-&FPGA原语综合。操作系统可以实时检测目前哪一些函数正被频繁调用,将其翻译后在FPGA上综合。 A:顺序的运算处理FPGA不占优势,CPU的ALU是高度优化过的,要比FPGA的实现版本强。这样做得不偿失。2.高性能需求应用为其编写HDL模块,运行时综合以实现加速,如网页服务程序、数据库引擎等。 A: 除非是数据密集型同时又是可以并行处理的应用场景,不然加速意义不大。3.获得不具备的硬件功能,如新一代CPU的新增指令集,更大的Cache,TPM芯片。(开源硬件? A: FPGA在开发新硬件功能的原型本来就是行业里一直都在做的事情。一旦特性稳定下来,都会走ASIC的路子。主要是成本的考虑。4.在FPGA上实现操作系统内核。可以让微内核概念变得真正可行,因为如果FPGA模块可以掌控外围硬件的话,syscall便不需要进行状态切换。 A: 为啥让FPGA掌控外围了,就不用状态切换了?5.作为一个监视系统来监视宿主系统的运行状态。A: 通信系统或者服务器设计里面有这样的案例。更常见的是用另一颗小CPU来监控。IBM Bluemix
点击按钮,开始云上的开发!
developerWorks 社区
本文是关于实时 Java™的 (共 5 部分)的第二篇,考察了 Java 语言的本地代码编译所涉及的一些问题。单独使用动态(即时)编译或静态(提前)编译都不能满足所有 Java 应用程序的需求。作者在各种执行环境中对这两种编译技术进行了比较,对二者如何相互补充进行了展示。
, 咨询软件开发人员, IBM Toronto Lab
Mark Stoodley 在 2001 年从多伦多大学获得计算机工程的博士学位,并于 2002 年加入 IBM 多伦多实验室,研究 Java JIT 编译技术。从 2005 年起,通过采用现有的 JIT 编译器并在实时环境中进行操作,他开始为 IBM WebSphere Real Time 开发 JIT 技术。他现在是 Java 编译控制团队的团队负责人,从事在本地代码的执行环境中提高本地代码编译效率的工作。工作以外,他喜欢收拾自己的家。
(), 软件开发人员, IBM Toronto Lab
Kenneth Ma 2003 年在 Waterloo 大学毕业,获得了电子工程应用科学的学士学位,此后不久他成为 IBM 的专职开发人员。先前在 IBM 实习期间,他从事 IBM 的 WebSphere 平台上的 iSeries 工具开发工作。Kenneth 现在是 IBM Testarossa JIT Compiler 团队的一员。在过去两年里,他一直致力于实现和改进 IBM J9 Java 虚拟机的 AOT 编译技术,最近从事将该技术迁移到 Java SE 环境的工作。
(), 软件开发人员, IBM Toronto Lab
Marius Lut 在罗马尼亚的 Timisoara 工艺大学获得了自动化和计算机工程学位。他在 1998 年加入 IBM 多伦多实验室。从那以后他从事 z/OS 的 IBM HPJ 静态编译器、IBM Sovereign JIT 编译器的开发工作,最近三年开发了 IBM Testarossa JIT 技术。他拥有 J2SE、J2ME 编译器、嵌入式系统的软件开发与设计、RT 环境、大型机和基于 Intel 处理器的系统等领域的开发经验。
Java 应用程序的性能经常成为开发社区中的讨论热点。因为该语言的设计初衷是使用解释的方式支持应用程序的可移植性目标,早期 Java 运行时所提供的性能级别远低于 C 和 C++ 之类的编译语言。尽管这些语言可以提供更高的性能,但是生成的代码只能在有限的几种系统上执行。在过去的十年中,Java 运行时供应商开发了一些复杂的动态编译器,通常称作即时(Just-in-time,JIT)编译器。程序运行时,JIT 编译器选择将最频繁执行的方法编译成本地代码。运行时才进行本地代码编译而不是在程序运行前进行编译(用 C 或 C++ 编写的程序正好属于后一情形),保证了可移植性的需求。有些 JIT 编译器甚至不使用解释程序就能编译所有的代码,但是这些编译器仍然通过在程序执行时进行一些操作来保持 Java 应用程序的可移植性。由于动态编译技术的多项改进,在很多应用程序中,现代的 JIT 编译器可以产生与 C 或 C++ 静态编译相当的应用程序性能。但是,仍然有很多软件开发人员认为 —— 基于经验或者传闻 —— 动态编译可能严重干扰程序操作,因为编译器必须与应用程序共享 CPU。一些开发人员强烈呼吁对 Java 代码进行静态编译,并且坚信那样可以解决性能问题。对于某些应用程序和执行环境而言,这种观点是正确的,静态编译可以极大地提高 Java 性能,或者说它是惟一的实用选择。但是,静态地编译 Java 应用程序在获得高性能的同时也带来了很多复杂性。一般的 Java 开发人员可能并没有充分地感受到 JIT 动态编译器的优点。本文考察了 Java 语言静态编译和动态编译所涉及的一些问题,重点介绍了实时 (RT) 系统。简要描述了 Java 语言解释程序的操作原理并说明了现代 JIT 编译器执行本地代码编译的优缺点。介绍了 IBM®在 WebSphere®Real Time 中发布的 AOT 编译技术和它的一些优缺点。然后比较了这两种编译策略并指出了几种比较适合使用 AOT 编译的应用程序领域和执行环境。要点在于这两种编译技术并不互斥:即使在使用这两种技术最为有效的各种应用程序中,它们也分别存在一些影响应用程序的优缺点。执行 Java 程序Java 程序最初是通过 Java SDK 的 javac程序编译成本地的与平台无关的格式(类文件)。可将此格式看作 Java 平台,因为它定义了执行 Java 程序所需的所有信息。Java 程序执行引擎,也称作 Java 运行时环境(JRE),包含了为特定的本地平台实现 Java 平台的虚拟机。例如,基于 Linux®的 Intel x86 平台、Sun Solaris 平台和 AIX®操作系统上运行的 IBM System p™平台,每个平台都拥有一个 JRE。这些 JRE 实现实现了所有的本地支持,从而可以正确执行为 Java 平台编写的程序。Java 平台程序表示的一个重要部分是 字节码序列,它描述了 Java 类中每个方法所执行的操作。字节码使用一个理论上无限大的操作数堆栈来描述计算。这个基于堆栈的程序表示提供了平台无关性,因为它不依赖任何特定本地平台的 CPU 中可用寄存器的数目。可在操作数堆栈上执行的操作的定义都独立于所有本地处理器的指令集。Java 虚拟机(JVM)规范定义了这些字节码的执行(参见 )。执行 Java 程序时,用于任何特定本地平台的任何 JRE 都必须遵守 JVM 规范中列出的规则。
因为基于堆栈的本地平台很少(Intel X87 浮点数协处理器是一个明显的例外),所以大多数本地平台不能直接执行 Java 字节码。为了解决这个问题,早期的 JRE 通过 解释字节码来执行 Java 程序。即 JVM 在一个循环中重复操作:获取待执行的下一个字节码。解码。从操作数堆栈获取所需的操作数。按照 JVM 规范执行操作。将结果写回堆栈。这种方法的优点是其简单性:JRE 开发人员只需编写代码来处理每种字节码即可。并且因为用于描述操作的字节码少于 255 个,所以实现的成本比较低。当然,缺点是性能:这是一个早期造成很多人对 Java 平台不满的问题,尽管拥有很多其他优点。解决与 C 或 C++ 之类的语言之间的性能差距意味着,使用不会牺牲可移植性的方式开发用于 Java 平台的本地代码编译。编译 Java 代码尽管传闻中 Java 编程的 “一次编写,随处运行” 的口号可能并非在所有情况下都严格成立,但是对于大量的应用程序来说情况确实如此。另一方面,本地编译本质上是特定于平台的。那么 Java 平台如何在不牺牲平台无关性的情况下实现本地编译的性能?答案就是使用 JIT 编译器进行动态编译,这种方法已经使用了十年(参见图 1):图 1. JIT 编译器使用 JIT 编译器时,Java 程序按每次编译一个方法的形式进行编译,因为它们在本地处理器指令中执行以获得更高的性能。此过程将生成方法的一个内部表示,该表示与字节码不同但是其级别要高于目标处理器的本地指令。(IBM JIT 编译器使用一个表达式树序列表示方法的操作。)编译器执行一系列优化以提高质量和效率,最后执行一个代码生成步骤将优化后的内部表示转换成目标处理器的本地指令。生成的代码依赖运行时环境来执行一些活动,比如确保类型转换的合法性或者对不能在代码中直接执行的某些类型的对象进行分配。JIT 编译器操作的编译线程与应用程序线程是分开的,因此应用程序不需要等待编译的执行。图 1 中还描述了用于观察执行程序行为的分析框架,通过周期性地对线程取样找出频繁执行的方法。该框架还为专门进行分析的方法提供了工具,用来存储程序的此次执行中可能不会改变的动态值。因为这个 JIT 编译过程在程序执行时发生,所以能够保持平台无关性:发布的仍然是中立的 Java 平台代码。C 和 C++ 之类的语言缺乏这种优点,因为它们在程序执行前进行本地编译;发布给(本地平台)执行环境的是本地代码。挑战尽管通过 JIT 编译保持了平台无关性,但是付出了一定代价。因为在程序执行时进行编译,所以编译代码的时间将计入程序的执行时间。任何编写过大型 C 或 C++ 程序的人都知道,编译过程往往较慢。为了克服这个缺点,现代的 JIT 编译器使用了下面两种方法的任意一种(某些情况下同时使用了这两种方法)。第一种方法是:编译所有的代码,但是不执行任何耗时多的分析和转换,因此可以快速生成代码。由于生成代码的速度很快,因此尽管可以明显观察到编译带来的开销,但是这很容易就被反复执行本地代码所带来的性能改善所掩盖。第二种方法是:将编译资源只分配给少量的频繁执行的方法(通常称作 热方法)。低编译开销更容易被反复执行热代码带来的性能优势掩盖。很多应用程序只执行少量的热方法,因此这种方法有效地实现了编译性能成本的最小化。动态编译器的一个主要的复杂性在于权衡了解编译代码的预期获益使方法的执行对整个程序的性能起多大作用。一个极端的例子是,程序执行后,您非常清楚哪些方法对于这个特定的执行的性能贡献最大,但是编译这些方法毫无用处,因为程序已经完成。而在另一个极端,程序执行前无法得知哪些方法重要,但是每种方法的潜在受益都最大化了。大多数动态编译器的操作介于这两个极端之间,方法是权衡了解方法预期获益的重要程度。Java 语言需要动态加载类这一事实对 Java 编译器的设计有着重要的影响。如果待编译代码引用的其他类还没有加载怎么办?比如一个方法需要读取某个尚未加载的类的静态字段值。Java 语言要求第一次执行类引用时加载这个类并将其解析到当前的 JVM 中。直到第一次执行时才解析引用,这意味着没有地址可供从中加载该静态字段。编译器如何处理这种可能性?编译器生成一些代码,用于在没有加载类时加载并解析类。类一旦被解析,就会以一种线程安全的方式修改原始代码位置以便直接访问静态字段的地址,因为此时已获知该地址。IBM JIT 编译器中进行了大量的努力以便使用安全而有效率的代码补丁技术,因此在解析类之后,执行的本地代码只加载字段的值,就像编译时已经解析了字段一样。另外一种方法是生成一些代码,用于在查明字段的位置以前一直检查是否已经解析字段,然后加载该值。对于那些由未解析变成已解析并被频繁访问的字段来说,这种简单的过程可能带来严重的性能问题。动态编译的优点动态地编译 Java 程序有一些重要的优点,甚至能够比静态编译语言更好地生成代码,现代的 JIT 编译器常常向生成的代码中插入挂钩以收集有关程序行为的信息,以便如果要选择方法进行重编译,就可以更好地优化动态行为。关于此方法的一个很好的例子是收集一个特定 arraycopy操作的长度。如果发现每次执行操作时该长度基本不变,则可以为最频繁使用的 arraycopy长度生成专门的代码,或者可以调用调整为该长度的代码序列。由于内存系统和指令集设计的特性,用于复制内存的最佳通用例程的执行速度通常比用于复制特定长度的代码慢。例如,复制 8 个字节的对齐的数据可能需要一到两条指令直接复制,相比之下,使用可以处理任意字节数和任意对齐方式的一般复制循环可能需要 10 条指令来复制同样的 8 个字节。但是,即使此类专门的代码是为某个特定的长度生成的,生成的代码也必须正确地执行其他长度的复制。生成代码只是为了使常见长度的操作执行得更快,因此平均下来,性能得到了改进。此类优化对大多数静态编译语言通常不实用,因为所有可能的执行中长度恒定的操作比一个特定程序执行中长度恒定的操作要少得多。此类优化的另一个重要的例子是基于类层次结构的优化。例如,一个虚方法调用需要查看接收方对象的类调用,以便找出哪个实际目标实现了接收方对象的虚方法。研究表明:大多数虚调用只有一个目标对应于所有的接收方对象,而 JIT 编译器可以为直接调用生成比虚调用更有效率的代码。通过分析代码编译后类层次结构的状态,JIT 编译器可以为虚调用找到一个目标方法,并且生成直接调用目标方法的代码而不是执行较慢的虚调用。当然,如果类层次结构发生变化,并且出现另外的目标方法,则 JIT 编译器可以更正最初生成的代码以便执行虚调用。在实践中,很少需要作出这些更正。另外,由于可能需要作出此类更正,因此静态地执行这种优化非常麻烦。因为动态编译器通常只是集中编译少量的热方法,所以可以执行更主动的分析来生成更好的代码,使编译的回报更高。事实上,大部分现代的 JIT 编译器也支持重编译被认为是热方法的方法。可以使用静态编译器(不太强调编译时间)中常见的非常主动的优化来分析和转换这些频繁执行的方法,以便生成更好的代码并获得更高的性能。这些改进及其他一些类似的改进所产生的综合效果是:对于大量的 Java 应用程序来说,动态编译已经弥补了与 C 和 C++ 之类语言的静态本地编译性能之间的差距,在某些情况下,甚至超过了后者的性能。缺点但是,动态编译确实具有一些缺点,这些缺点使它在某些情况下算不上一个理想的解决方案。例如,因为识别频繁执行的方法以及编译这些方法需要时间,所以应用程序通常要经历一个准备过程,在这个过程中性能无法达到其最高值。在这个准备过程中出现性能问题有几个原因。首先,大量的初始编译可能直接影响应用程序的启动时间。不仅这些编译延迟了应用程序达到稳定状态的时间(想像 Web 服务器经历一个初始阶段后才能够执行实际有用的工作),而且在准备阶段中频繁执行的方法可能对应用程序的稳定状态的性能所起的作用也不大。如果 JIT 编译会延迟启动又不能显著改善应用程序的长期性能,则执行这种编译就非常浪费。虽然所有的现代 JVM 都执行调优来减轻启动延迟,但是并非在所有情况下都能够完全解决这个问题。其次,有些应用程序完全不能忍受动态编译带来的延迟。如 GUI 接口之类交互式应用程序就是这样的例子。在这种情况下,编译活动可能对用户使用造成不利影响,同时又不能显著地改善应用程序的性能。最后,用于实时环境并具有严格的任务时限的应用程序可能无法忍受编译的不确定性性能影响或动态编译器本身的内存开销。因此,虽然 JIT 编译技术已经能够提供与静态语言性能相当(甚至更好)的性能水平,但是动态编译并不适合于某些应用程序。在这些情况下,Java 代码的提前(Ahead-of-time,AOT)编译可能是合适的解决方案。AOT Java 编译大致说来,Java 语言本地编译应该是为传统语言(如 C++ 或 Fortran)而开发的编译技术的一个简单应用。不幸的是,Java 语言本身的动态特性带来了额外的复杂性,影响了 Java 程序静态编译代码的质量。但是基本思想仍然是相同的:在程序执行前生成 Java 方法的本地代码,以便在程序运行时直接使用本地代码。目的在于避免 JIT 编译器的运行时性能消耗或内存消耗,或者避免解释程序的早期性能开销。挑战动态类加载是动态 JIT 编译器面临的一个挑战,也是 AOT 编译的一个更重要的问题。只有在执行代码引用类的时候才加载该类。因为是在程序执行前进行 AOT 编译的,所以编译器无法预测加载了哪些类。就是说编译器无法获知任何静态字段的地址、任何对象的任何实例字段的偏移量或任何调用的实际目标,甚至对直接调用(非虚调用)也是如此。在执行代码时,如果证明对任何这类信息的预测是错误的,这意味着代码是错误的并且还牺牲了 Java 的一致性。因为代码可以在任何环境中执行,所以类文件可能与代码编译时不同。例如,一个 JVM 实例可能从磁盘的某个特定位置加载类,而后面一个实例可能从不同的位置甚至网络加载该类。设想一个正在进行 bug 修复的开发环境:类文件的内容可能随不同的应用程序的执行而变化。此外,Java 代码可能在程序执行前根本不存在:比如 Java 反射服务通常在运行时生成新类来支持程序的行为。缺少关于静态、字段、类和方法的信息意味着严重限制了 Java 编译器中优化框架的大部分功能。内联可能是静态或动态编译器应用的最重要的优化,但是由于编译器无法获知调用的目标方法,因此无法再使用这种优化。AOT 代码因此必须在没有解析每个静态、字段、类和方法引用的情况下生成。执行时,每个这些引用必须利用当前运行时环境的正确值进行更新。这个过程可能直接影响第一次执行的性能,因为在第一次执行时将解析所有引用。当然,后续执行将从修补代码中获益,从而可以更直接地引用实例、静态字段或方法目标。另外,为 Java 方法生成的本地代码通常需要使用仅在单个 JVM 实例中使用的值。例如,代码必须调用 JVM 运行时中的某些运行时例程来执行特定操作,如查找未解析的方法或分配内存。这些运行时例程的地址可能在每次将 JVM 加载到内存时变化。因此 AOT 编译代码需要绑定到 JVM 的当前执行环境中,然后才能执行。其他的例子有字符串的地址和常量池入口的内部位置。在 WebSphere Real Time 中,AOT 本地代码编译通过 jxeinajar工具(参见图 2)来执行。该工具对 JAR 文件中所有类的所有方法应用本地代码编译,也可以选择性地对需要的方法应用本地代码编译。结果被存储到名为 Java eXEcutable (JXE) 的内部格式中,但是也可轻松地存储到任意的持久性容器中。图 2. jxeinajar您可能认为对所有的代码进行静态编译是最好的方法,因为可以在运行时执行最大数量的本地代码。但是此处可以作出一些权衡。编译的方法越多,代码占用的内存就越多。编译后的本地代码大概比字节码大 10 倍:本地代码本身的密度比字节码小,而且必须包含代码的附加元数据,以便将代码绑定到 JVM 中,并且在出现异常或请求堆栈跟踪时正确执行代码。构成普通 Java 应用程序的 JAR 文件通常包含许多很少执行的方法。编译这些方法会消耗内存却没有什么预期收益。相关的内存消耗包括以下过程:将代码存储到磁盘上、从磁盘取出代码并装入 JVM,以及将代码绑定到 JVM。除非多次执行代码,否则这些代价不能由本地代码相对解释的性能优势来弥补。跟大小问题相违背的一个事实是:在编译过的方法和解释过的方法之间进行的调用(即编译过的方法调用解释过的方法,或者相反)可能比这两类方法各自内部之间进行的调用所需的开销大。动态编译器通过最终编译所有由 JIT 编译代码频繁调用的那些解释过的方法来减少这项开销,但是如果不使用动态编译器,则这项开销就不可避免。因此如果是选择性地编译方法,则必须谨慎操作以使从已编译方法到未编译方法的转换最小化。为了在所有可能的执行中都避免这个问题而选择正确的方法会非常困难。优点虽然 AOT 编译代码具有上述的缺点和挑战,但是提前编译 Java 程序可以提高性能,尤其是在不能将动态编译器作为有效解决方案的环境中。可以通过谨慎地使用 AOT 编译代码加快应用程序启动,因为虽然这种代码通常比 JIT 编译代码慢,但是却比解释代码快很多倍。此外,因为加载和绑定 AOT 编译代码的时间通常比检测和动态编译一个重要方法的时间少,所以能够在程序执行的早期达到那样的性能。类似地,交互式应用程序可以很快地从本地代码中获益,无需使用引起较差响应能力的动态编译。RT 应用程序也能从 AOT 编译代码中获得重要的收益:更具确定性的性能超过了解释的性能。WebSphere Real Time 使用的动态 JIT 编译器针对在 RT 系统中的使用进行了专门的调整。使编译线程以低于 RT 任务的优先级操作,并且作出了调整以避免生成带有严重的不确定性性能影响的代码。但是,在一些 RT 环境中,出现 JIT 编译器是不可接受的。此类环境通常需要最严格的时限管理控制。在这些例子中,AOT 编译代码可以提供比解释过的代码更好的原始性能,又不会影响现有的确定性。消除 JIT 编译线程甚至消除了启动更高优先级 RT 任务时发生的线程抢占所带来的性能影响。优缺点统计动态(JIT)编译器支持平台中立性,并通过利用应用程序执行的动态行为和关于加载的类及其层次结构的信息来生成高质量的代码。但是 JIT 编译器具有一个有限的编译时预算,而且会影响程序的运行时性能。另一方面,静态(AOT)编译器则牺牲了平台无关性和代码质量,因为它们不能利用程序的动态行为,也不具有关于加载的类或类层次结构的信息。AOT 编译拥有有效无限制的编译时预算,因为 AOT 编译时间不会影响运行时性能,但是在实践中开发人员不会长期等待静态编译步骤的完成。表 1 总结了本文讨论的 Java 语言动态和静态编译器的一些特性:表 1. 比较编译技术动态 (JIT)静态 (AOT)平台无关性有无代码质量优秀良好利用动态行为是否类和层次结构的知识有无编译时间有限制,有运行时成本限制很少,无运行时成本运行时性能影响有无编译方式需要谨慎编译,由 JIT 处理需要谨慎编译,由开发人员处理两种技术都需要谨慎选择编译的方法以实现最高的性能。对动态编译器而言,编译器自身作出决策,而对于静态编译器,由开发人员作出选择。让 JIT 编译器选择编译的方法是不是优点很难说,取决于编译器在给定情形中推断能力的好坏。在大多数情况下,我们认为这是一种优点。因为它们可以最好地优化运行中的程序,所以 JIT 编译器在提供稳定状态性能方面更胜一筹,而这一点在大量的生产 Java 系统中最为重要。静态编译可以产生最佳的交互式性能,因为没有运行时编译行为来影响用户预期的响应时间。通过调整动态编译器可以在某种程度上解决启动和确定性性能问题,但是静态编译在需要时可提供最快的启动速度和最高级别的确定性。表 2 在四种不同的执行环境中对这两种编译技术进行了比较:表 2. 使用这些技术的最佳环境动态 (JIT)静态 (AOT)启动性能可调整,但不是最好最好稳定状态性能最好好交互式性能一般良好确定性性能可调整,但不是最好最好图 3 展示了启动性能和稳定状态性能的总体趋势:图 3. AOT 和 JIT 的性能对比使用 JIT 编译器的初始阶段性能很低,因为要首先解释方法。随着编译方法的增多及 JIT 执行编译所需时间的缩短,性能曲线逐渐升高最后达到性能峰值。另一方面,AOT 编译代码启动时的性能比解释的性能高很多,但是无法达到 JIT 编译器所能达到的最高性能。将静态代码绑定到 JVM 实例中会产生一些开销,因此开始时的性能比稳定状态的性能值低,但是能够比使用 JIT 编译器更快地达到稳定状态的性能水平。没有一种本地代码编译技术能够适合所有的 Java 执行环境。某种技术所擅长的通常正是其他技术的弱项。出于这个原因,需要同时使用这两种编译技术以满足 Java 应用程序开发人员的要求。事实上,可以结合使用静态和动态编译以便提供最大可能的性能提升 —— 但是必须具备平台无关性,它是 Java 语言的主要卖点,因此不成问题。结束语本文探讨了 Java 语言本地代码编译的问题,主要介绍了 JIT 编译器形式的动态编译和静态 AOT 编译,比较了二者的优缺点。虽然动态编译器在过去的十年里实现了极大的成熟,使大量的各种 Java 应用程序可以赶上或超过静态编译语言(如 C++ 或 Fortran)所能够达到的性能。但是动态编译在某些类型的应用程序和执行环境中仍然不太合适。虽然 AOT 编译号称动态编译缺点的万能解决方案,但是由于 Java 语言本身的动态特性,它也面临着提供本地编译全部潜能的挑战。这两种技术都不能解决 Java 执行环境中本地代码编译的所有需求,但是反过来又可以在最有效的地方作为工具使用。这两种技术可以相互补充。能够恰当地使用这两种编译模型的运行时系统可以使很大范围内的应用程序开发环境中的开发人员和用户受益。
参考资料 :阅读本系列的其他部分。
:现在可以下载 JVM 规范的第二版。:您将在 Java Community Process 站点找到 RJSJ。
:阅读 WebSphere Real Time 的产品声明。
“”(Martyn Honeyford,developerWorks,2002 年 1 月):讨论从 Java 源代码生成本地代码的利弊。:提供了大量关于 Java 编程各个方面的文章。:WebSphere Real Time 利用了标准的 Java 技术并且没有损失确定性,使应用程序依赖于精确的响应时间。
:访问作者的 IBM alphaWorks 研究站点,查找用于实时 Java 的先进技术。
通过参与 加入 。
developerWorks: 登录
标有星(*)号的字段是必填字段。
保持登录。
单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件。
在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。
所有提交的信息确保安全。
选择您的昵称
当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。昵称长度在 3 至 31 个字符之间。
您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。
标有星(*)号的字段是必填字段。
(昵称长度在 3 至 31 个字符之间)
单击提交则表示您同意developerWorks 的条款和条件。 .
所有提交的信息确保安全。
文章、教程、演示,帮助您构建、部署和管理云应用。
立即加入来自 IBM 的专业 IT 社交网络。
为灾难恢复构建应用,赢取现金大奖。
static.content.url=/developerworks/js/artrating/SITE_ID=10Zone=Java technologyArticleID=221036ArticleTitle=实时 Java,第 2 部分: 比较编译技术publish-date=

我要回帖

更多关于 openwrt x86 编译 的文章

 

随机推荐